本文最后更新于 2024-07-26T20:51:31+08:00
爬虫核心:
1.爬取网页:爬取整个网页,包含了网页中所有内容
2.解析数据:将网页中你得到的数据 进行解析
3.难点:爬虫和反爬虫之间的博弈
爬虫分类:
通用爬虫:
实例:
百度、360、google、搜狗等搜索引擎----伯乐在线
功能:
访问网页-->抓取数据-->数据存储-->数据处理-->提供检索服务
robots协议
一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起不到限制作用
自己写的爬虫无须遵守
网站排名:
1.根据pagerank算法值进行排名(参考网站流量、点击率等指标)
2.百度竞价排名
缺点:
1.抓取的数据大多是无用的
2.不能根据用户的需求来精准获取数据
聚焦爬虫:
功能:
根据需求,实现爬虫程序,抓取需要的数据
设计思路:
1.确定要爬取的url
如何获取url
2.模拟浏览器通过http协议访问url,获取服务器返回的html代码
如何访问
3.解析html字符串(根据一定规则提取需要的数据)
如何解析
反爬手段:
1.User-Agent:
user Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版 CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
2.代理IP
西次代理
快代理
什么是高匿名、匿名和透明代理?它们有什么区别?
1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。
2.使用匿名代理,对方服务器可以知道你使用了代理, 但不知道你的真实IP。
3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
3.验证码访问
打码平台
云打码平台
超级
4.动态加载网页 网站返回的是js数据 并不是网页的真实数据
selenium驱动真实的浏览器发送请求
5.数据加密
分析js代码
Urllib的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #使用urllib获取百度首页源码 import urllib.request
#1.定义一个url 就是你要访问的地址 url='http://www.baidu.com'
#2.模拟浏览器向服务器发送请求 response-响应 response=urllib.request.urlopen(url) #print(response)
#3.获取响应中的页面的源码 content-内容 #read方法 返回的是字节形式的二进制数据 (b') #将二进制数据转为字符串---->解码 方法:decode('编码的格式') content=response.read().decode('utf-8')
#打印 print(content)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import urllib.request url='http://www.baidu.com'
respone=urllib.request.urlopen(url)
print(type(respone))#<class 'http.client.HTTPResponse'>
content=respone.read() content=respone.read(5)#读5个字节
content=respone.readline()
content=respone.readlines()
print(respone.getcode())
print(respone.geturl())
print(respone.getheaders())
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import urllib.request #下载网页 url_page='http://www.baidu.com' #url代表下载路径,filename是文件名字 urllib.request.urlretrieve(url_page,"baidu.html")
#下载图片 url_imag='https://gips1.baidu.com/it/u=869589177,1848598878&fm=3028&app=3028&size=w931&q=75&n=0&f=PNG&fmt=auto&maxorilen2heic=2000000' urllib.request.urlretrieve(url=url_imag,filename='image.jpg')
#下载视频 url_video='https://vdept3.bdstatic.com/mda-qgd2891c16cc1p35/360p/h264/1720920969149508765/mda-qgd2891c16cc1p35.mp4?v_from_s=hkapp-haokan-nanjing&auth_key=1720950217-0-0-c76b0b6fef675d36234a30b6db923966&bcevod_channel=searchbox_feed&pd=1&cr=0&cd=0&pt=3&logid=2617830577&vid=15798241631673631806&klogid=2617830577&abtest=101830_2-17451_1-3000225_1' urllib.request.urlretrieve(url_video,"abc.mp4")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import urllib.request import urllib.parse url='https://www.baidu.com'# url='http://www.baidu.com'
headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299' }
request=urllib.request.Request(url=url,headers=headers) response=urllib.request.urlopen(request) content=response.read().decode('utf-8') print(content)
url='https://www.baidu.com/s?wd='
name=urllib.parse.quote("你好") print(name) url=url+name request=urllib.request.Request(url=url,headers=headers) response=urllib.request.urlopen(request) content=response.read().decode('utf-8') print(content)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import urllib.request import urllib.parse data={ "wd":'你好', "sex":'2', } #多个参数传参 a=urllib.parse.urlencode(data) url='https://www.baidu.com/s?'+a
hearders={ 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' } req=urllib.request.Request(url=url,headers=hearders) req=urllib.request.urlopen(req) print(req.read().decode('utf-8'))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import urllib.request import urllib.parse url='https://fanyi.baidu.com/sug' headers={ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36" } data={ 'kw': 'hello' }
data=urllib.parse.urlencode(data).encode('utf-8')
requests=urllib.request.Request(url=url,data=data,headers=headers)
response=urllib.request.urlopen(requests) content=response.read().decode('utf-8') print(content) print(type(content))
import json content_dict=json.loads(content) print(content_dict)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import urllib.request import urllib.parse url='https://fanyi.baidu.com/v2transapi?from=en&to=zh' headers={ 'Cookie': 'BIDUPSID=4051DD61A35ADB02F6DBB9362C65230B; PSTM=1691472145; BAIDUID=4051DD61A35ADB02E71B03D86B63E5F3:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; APPGUIDE_10_7_2=1; smallFlowVersion=old; BDUSS=25reVZxN3puRTlZRmVkYkNpQ2REYkx1TFRyYk8wd3d-ei1ON3RGMjdwUnFyRzVtRUFBQUFBJCQAAAAAAQAAAAEAAABEqXCBU3djbWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGofR2ZqH0dmd; BDUSS_BFESS=25reVZxN3puRTlZRmVkYkNpQ2REYkx1TFRyYk8wd3d-ei1ON3RGMjdwUnFyRzVtRUFBQUFBJCQAAAAAAQAAAAEAAABEqXCBU3djbWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGofR2ZqH0dmd; APPGUIDE_10_7_8=1; APPGUIDE_10_7_1=1; MCITY=-286%3A; H_PS_PSSID=60277_60361; H_WISE_SIDS=60277_60361; H_WISE_SIDS_BFESS=60277_60361; BDORZ=FAE1F8CFA4E8841CC28A015FEAEE495D; BA_HECTOR=21ah200120840584ak05050h0s6f6o1j975q01v; ZFY=6TGjMTdRv2Hm2U6qBurH:ANpw:BH01zqfPCmxsI4SsNxs:C; BAIDUID_BFESS=4051DD61A35ADB02E71B03D86B63E5F3:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=2; delPer=0; ab_sr=1.0.1_YjllYzZiNGZmMGQ3Y2MzYTA3ZGZiN2U4YzJhMDRlNzI1MjM2Nzk4ZmI3ZDI3NzQ0N2Y3MmQ5NzdmYTJlYjlhNzgwZjMxY2IyMjg3NmMzZjI5MTljN2U2ZDRmMmU2N2NmMmUxMDZhZjI0NTFmM2RhNTgxMjVmNTU4ZDM4Y2IxNzY2MDczODkyNzU3YWM2NDI3ZjIwNzgwOTVhNmJmNmVjNDM3ZWJlY2U2MjM2Nzg3MjcyZTM3ZWM4MjI0MzYxNzEx' }
data={ 'from': 'en', 'to': 'zh', 'query': 'love', 'transtype': 'realtime', 'simple_means_flag': '3', 'sign': '198772.518981', 'token': 'e4649cb1ca39571638fbe20768a03def', 'domain': 'common', 'ts': '1720950443458' } data=urllib.parse.urlencode(data).encode('utf-8') req=urllib.request.Request(url,data,headers) res=urllib.request.urlopen(req) html=res.read().decode('utf-8') #print(html)#'errmsg': '未知错误' import json html=json.loads(html) print(html)
|
1 2 3 4 5 6 7 8 9 10 11 12
| #适用的场景:数据采集的时候 绕过登录 然后进入到某个界面 #个人信息界面是utf-8 但还是报编码错误 是因为跳转到了登录页面 登录页面不是utf-8 import urllib.request url='https://weibo.cn/7925491585/info' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36', 'Cookie':'SCF=AnksCtQWDdlW1_dCN1d8WubORYx1AdsxJbQzeDBC5ab_rgy9BkWZoxyuXaqeQLRfPfYnSD9kqnKCexcWcpA2xdk.; SUB=_2A25LkMyvDeRhGeFH6VcV-S_JwzmIHXVo7EBnrDV6PUJbktAGLRfTkW1Ne4hh_w1YQrFWxhUqGEpVVFfxFbjCBdT9; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WWLy2U7lfHOX814SNTxy2025NHD95QN1KzfSh.pSKnfWs4DqcjMi--NiK.Xi-2Ri--ciKnRi-zNS0.ESKB4eK-RSBtt; SSOLoginState=1721023743; ALF=1723615743; _T_WM=1b06872d7da83be4099f7988c6f4fab0' } requests=urllib.request.Request(url=url,headers=headers) html=urllib.request.urlopen(requests).read().decode('utf-8') with open('weibo.html','w',encoding='utf-8')as f: f.write(html)
|
Handler处理器
定制更高级的请求头(动态cookie和代理不能使用请求对象的定制)
1 2 3 4 5 6 7 8 9 10 11 12 13
| import urllib.request url = "http://www.baidu.com" headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'} request=urllib.request.Request(url=url,headers=headers)
handler=urllib.request.HTTPHandler()
opener=urllib.request.build_opener(handler)
response=opener.open(request) print(response.read().decode('utf-8'))
|
代理服务器
1.代理的常用功能? 1.突破自身IP访问限制,访问国外站点
2.访问一些单位或团体内部资源
扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),
使用教育网内地址段免费代理服
务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
3.提高访问速度
扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。
4.隐藏真实IP 扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
2.代码配置代理 创建Reugest对象 创建ProxyHandler对象
用handler对象创建opener对象 使用opener.open函数发送请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import urllib.request url='http://www.baidu.com/s?wd=ip' headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' } req=urllib.request.Request(url=url,headers=headers)
proxies={ 'http':'125.77.25.177:8090' } handler=urllib.request.ProxyHandler(proxies=proxies)
opener=urllib.request.build_opener(handler) res=opener.open(req)
content=res.read().decode('utf-8') with open('daili.html','w',encoding='utf-8')as f: f.write(content)
|
xpath基本语法: 1.路径查询 //:查找所有子孙节点,不考虑层级关系
/:找直接子节点 2.谓词查询 //div[@id] //div[@id="maincontent"] 3.属性查询 //@class 4.模糊查询 //div[contains(@id, “he”)] //div[starts-with(@id, "he”)]
5.内容查询 //div/h1/text() 6.逻辑运算 //div[@id="head" and @class="s_down"]
//title|//price
Selenium
1.什么是selenium? (1)selenium是一个用于web应用程序测试的工具。
(2)selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
(3)支持通过各种driver(firfoxDriver,IternetExplorerpriver,operaDriver,chromeDriver)驱动
真实浏览器完成测试。 (4)selenium也是支持无界面浏览器操作的。
3.如何安装selenium? (1)操作谷歌浏览器驱动下载地址
http://chromedriver.storage.googleapis.com/index.html
(2)谷歌驱动和谷歌浏览器版本之间的映射表
http://blog.csdn.net/huilan_same/article/details/51896672
(3)查看谷歌浏览器版本 谷歌浏览器右上角-->帮助-->关于 (4)pip
install selenium
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| 1. 打开浏览器:`driver = webdriver.Chrome()`
2. 访问网址:`driver.get("Example Domain")`
3. 获取当前网址:`driver.current_url`
4. 获取页面标题:`driver.title`
5. 获取页面源码:`driver.page_source`
6. 刷新页面:`driver.refresh()`
7. 前进:`driver.forward()`
8. 后退:`driver.back()`
9. 等待元素出现:`WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "my-element")))`
10. 等待元素可点击:`WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "my-element")))`
11. 查找元素:`driver.find_element(By.ID, "my-element")`
12. 查找多个元素:`driver.find_elements(By.CLASS_NAME, "my-element")`
13. 单击元素:`element.click()`
14. 输入文本:`element.send_keys("text")`
15. 清除文本:`element.clear()`
16. 获取元素文本:`element.text`
17. 获取元素属性:`element.get_attribute("attribute-name")`
18. 设置元素属性:`element.set_attribute("attribute-name", "value")`
19. 滚动到元素:`driver.execute_script("arguments[0].scrollIntoView();", element)`
20. 获取元素位置:`element.location`
21. 获取元素大小:`element.size`
22. 获取元素是否可见:`element.is_displayed()`
23. 获取元素是否启用:`element.is_enabled()`
24. 获取元素是否选中:`element.is_selected()`
25. 提交表单:`element.submit()`
26. 切换到新窗口:`driver.switch_to.window("window-name")`
27. 切换到新标签页:`driver.switch_to.window("tab-name")`
28. 关闭当前窗口:`driver.close()`
29. 关闭所有窗口:`driver.quit()`
30. 设置隐式等待:`driver.implicitly_wait(10)`
31. 设置显式等待:`WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "my-element")))`
32. 执行 JavaScript 代码:`driver.execute_script("script")`
33. 获取浏览器日志:`driver.get_log("browser")`
34. 获取页面截图:`driver.save_screenshot("screenshot.png")`
35. 设置超时时间:`driver.set_page_load_timeout(10)`
36. 设置脚本超时时间:`driver.set_script_timeout(10)`
37. 忽略 SSL 证书错误:`driver.service.ignore_ssl_errors = True`
38. 设置代理:`driver.service.proxy = "http://proxy.example.com:8080"`
39. 设置用户代理:`driver.execute_cdp_cmd("Network.setUserAgentOverride", {"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"})`
40. 设置窗口大小:`driver.set_window_size(1024, 768)`
41. 最大化窗口:`driver.maximize_window()`
42. 还原窗口:`driver.minimize_window()`
43. 退出浏览器:`driver.quit()`
44. 等待元素出现:`WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "my-element")))`
45. 等待元素可点击:`WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "my-element")))`
46. 等待元素消失:`WebDriverWait(driver, 10).until(EC.invisibility_of_element_located((By.ID, "my-element")))`
47. 等待元素可见:`WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "my-element")))`
48. 等待元素不可见:`WebDriverWait(driver, 10).until(EC.invisibility_of_element_located((By.ID, "my-element")))`
49. 等待元素被选中:`WebDriverWait(driver, 10).until(EC.element_to_be_selected((By.ID, "my-element")))`
50. 等待元素未被选中:`WebDriverWait(driver, 10).until(EC.element_to_be_selected((By.ID, "my-element")))`
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome() driver.get("https://www.baidu.com")
#根据id找对象 ! button = driver.find_element(By.ID, 'su') print(button)
#根据标签属性的属性值获取对象 button=driver.find_element(By.NAME,'wd') print(button)
#根据xpath找对象 ! #find_elements找多个对象 button=driver.find_elements(By.XPATH,'//input[@id="su"]') print(button)
#根据标签名找对象 button=driver.find_elements(By.TAG_NAME,'input') print(button)
#使用bs4语法获取对象 ! button=driver.find_elements(By.CSS_SELECTOR,'#su') print(button)
#链接文本获取对象 button=driver.find_elements(By.LINK_TEXT,'新闻') print(button)
input("press twice ...")
|
requests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import requests url='http://www.baidu.com' response=requests.get(url)
print(type(response))#Response类型
response.encoding='utf-8'
print(response.text)
print(response.url)
print(response.content)
print(response.status_code)
print(response.headers)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import requests url='https://www.baidu.com/s?' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299' } data={ 'wd':'北京' } response=requests.get(url=url,params=data,headers=headers) response.encoding='utf-8' print(response.text)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import requests url='https://fanyi.baidu.com/v2transapi?from=en&to=zh' headers={ 'Cookie': 'BIDUPSID=4051DD61A35ADB02F6DBB9362C65230B; PSTM=1691472145; BAIDUID=4051DD61A35ADB02E71B03D86B63E5F3:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; APPGUIDE_10_7_2=1; smallFlowVersion=old; BDUSS=25reVZxN3puRTlZRmVkYkNpQ2REYkx1TFRyYk8wd3d-ei1ON3RGMjdwUnFyRzVtRUFBQUFBJCQAAAAAAQAAAAEAAABEqXCBU3djbWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGofR2ZqH0dmd; BDUSS_BFESS=25reVZxN3puRTlZRmVkYkNpQ2REYkx1TFRyYk8wd3d-ei1ON3RGMjdwUnFyRzVtRUFBQUFBJCQAAAAAAQAAAAEAAABEqXCBU3djbWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGofR2ZqH0dmd; APPGUIDE_10_7_8=1; APPGUIDE_10_7_1=1; MCITY=-286%3A; H_PS_PSSID=60277_60361; H_WISE_SIDS=60277_60361; H_WISE_SIDS_BFESS=60277_60361; BDORZ=FAE1F8CFA4E8841CC28A015FEAEE495D; BA_HECTOR=21ah200120840584ak05050h0s6f6o1j975q01v; ZFY=6TGjMTdRv2Hm2U6qBurH:ANpw:BH01zqfPCmxsI4SsNxs:C; BAIDUID_BFESS=4051DD61A35ADB02E71B03D86B63E5F3:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=2; delPer=0; ab_sr=1.0.1_YjllYzZiNGZmMGQ3Y2MzYTA3ZGZiN2U4YzJhMDRlNzI1MjM2Nzk4ZmI3ZDI3NzQ0N2Y3MmQ5NzdmYTJlYjlhNzgwZjMxY2IyMjg3NmMzZjI5MTljN2U2ZDRmMmU2N2NmMmUxMDZhZjI0NTFmM2RhNTgxMjVmNTU4ZDM4Y2IxNzY2MDczODkyNzU3YWM2NDI3ZjIwNzgwOTVhNmJmNmVjNDM3ZWJlY2U2MjM2Nzg3MjcyZTM3ZWM4MjI0MzYxNzEx' } data={ 'from': 'en', 'to': 'zh', 'query': 'eye', 'transtype': 'realtime', 'simple_means_flag': '3', 'sign': '198772.518981', 'token': 'e4649cb1ca39571638fbe20768a03def', 'domain': 'common', 'ts': '1720950443458' } response=requests.post(url,headers=headers,data=data) response.encoding='utf-8' import json res=json.loads(response.text) print(res)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #通过找登录接口我们发现 登陆的时候需要的参数很多 # __VIEWSTATE: kMzjZzs7cRpbwcfkAPNzVbfdDgGUVBsaauYiyk75HVukTeWAG7Ok8IvRmNaOVVKqwALNSRMwVtZYlx68J9h3MwudrcVXTfybdOvj3ASxaAloHxTgg7LfCD%2Fi1eE0tfaXtn8TS5XAHmPoRIbyZ9a8lq9s13k%3D # __VIEWSTATEGENERATOR: C93BE1AE # from: https%3A%2F%2Fwww.gushiwen.cn%2F # email: 3216243013%40qq.com # pwd: Jw_Y334u%3AD # code: SYOP # denglu: %E7%99%BB%E5%BD%95 #__VIEWSTATE、__VIEWSTATEGENERATOR是一个变量
#难点: #1.__VIEWSTATE、__VIEWSTATEGENERATOR 一般看不到的数据都在网页源码中 #<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="ezxzwyAx+ftix1tysT/DIxCv7xxlHPPSirfhRTyUrXq9PkN2UJwR6ho724M3seHZ9KXaVi9WbqeZtdE9MS99dTvz9fFwjkyiFnwlVgkf6cu84UM6pq6ZH9zMrNeBFqqNyqrNTvjPYfFe/L5VXLqOGssETao=" /> #<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="C93BE1AE" /> #获取网页源码,通过解析获取两个数值 import requests url_login='https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx' headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } response=requests.get(url=url_login,headers=headers) content=response.text #解析页面源码 from bs4 import BeautifulSoup soup=BeautifulSoup(content,'lxml') #解析出__VIEWSTATE VIEWSTATE=soup.select('#__VIEWSTATE')[0].attrs.get('value') #解析出__VIEWSTATEGENERATOR VIEWSTATEGENERATOR=soup.select('#__VIEWSTATEGENERATOR')[0].attrs.get('value')
#2.验证码 #获取验证码图片 #<img id="imgCode" style="cursor: pointer; float:left; margin-left:5px; margin-top:1px;" width="60" height="27" src="/RandCode.ashx" onclick="GetCodeImg()" alt="看不清,换一张"> code=soup.select('#imgCode')[0].attrs.get('src') code_url='https://so.gushiwen.cn/'+code #获取验证码图片 下载到本地 观察验证码 在控制台输入验证码
# import urllib.request#坑 # urllib.request.urlretrieve(code_url,'code.jpg')#坑--二次请求!验证码改变
#requests的session方法———通过session返回值就能使请求变成一个对象 session=requests.session() #验证码的url的内容 respon_code=session.get(code_url) #注意使用二进制数据 content_code=respon_code.content #'wb'——将二进制数据写入数据 with open('code.jpg','wb') as f: f.write(content_code)
import VerificationCode code_name=VerificationCode.yanzhengma('code.jpg')
url_post='https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx' data_post={ '__VIEWSTATE':VIEWSTATE, '__VIEWSTATEGENERATOR':VIEWSTATEGENERATOR, 'from': 'http://so.gushiwen.cn/user/collect.aspx', 'email': '[email protected]', 'pwd': 'Jw_Y334u:D5uSAZ', 'code': code_name, 'denglu': '登录' }
response_post=session.post(url=url_post,data=data_post,headers=headers)
#保存登录后的页面源码 content_post=response_post.text with open('gushiwen.html','w',encoding='utf-8') as f: f.write(content_post)
|
Scrapy
1.创建爬虫项目
scrapy startproject 项目名
1
| scrapy startproject scrapy_baidu
|
项目名不允许以数字开头,也不允许包含中文
2.创建爬虫文件
在项目下的spiders文件夹下创建爬虫文件--cd过去
scrapy genspider 爬虫文件的名字 要爬取的网页
一般不添加http协议
1
| scrapy genspider baidu www.baidu.com
|
1 2 3 4 5 6 7 8 9 10 11
| import scrapy
class BaiduSpider(scrapy.Spider): name = "baidu"#爬虫的名字 用于运行爬虫的时候使用的值 allowed_domains = ["www.baidu.com"]#允许访问的域名 start_urls = ["https://www.baidu.com"]#起始的url地址,指的是第一次要访问的域名,自动添加协议
def parse(self, response):#运行start_urls执行的方法 方法中的response就是返回的对象,相当于urllib.request.urlopen request.get() #print("123456789") pass
|
3.运行爬虫文件
scrapy crawl 爬虫的名字
1 2 3
| #robots协议 2024-07-17 16:15:22 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com/robots.txt> (referer: None) 2024-07-17 16:15:22 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com> (referer: None)
|
https://www.baidu.com/robots.txt
1 2 3 4
| #scrapy_baidu/scrapy_baidu/settings.py
# Obey robots.txt rules #ROBOTSTXT_OBEY = True#注释掉
|
scrapy的项目结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ├─scrapy_58tc#项目名字 │ │ scrapy.cfg │ │ │ └─scrapy_58tc#项目名字 │ │ items.py#定义数据结构的地方 爬取的数据都包含哪些 │ │ middlewares.py#中间件 代理 │ │ pipelines.py#管道 用来处理下载的数据 │ │ settings.py#配置文件 robots协议 ua定义 │ │ __init__.py │ │ │ ├─spiders#存储的是爬虫文件 │ │ │ tc.py#自定义的爬虫文件 核心功能文件 │ │ │ __init__.py │ │ │ │ │ └─__pycache__ │ │ tc.cpython-312.pyc │ │ __init__.cpython-312.pyc │ │ │ └─__pycache__ │ settings.cpython-312.pyc │ __init__.cpython-312.pyc
|
1 2 3 4 5 6 7 8 9 10
| content=response.text
content=response.body
a=response.xpath()
a.getall()
a.get()
|
进入到scrapy shell