爬虫的概念
- 爬虫是从事模拟浏览器发送请求,获取响应
爬虫的流程
- 准备url
- 准备start_url
- url地址规律不明显,总数不确定
- 通过代码提取下一页url
- xpath
- 寻找url地址,部分参数在当前的响应中
- 准备url_list
- 页面总数明确
- url地址规律明显
- 准备start_url
- 发送请求,获取响应
- 添加随机的User-Agent,防反爬虫
- 添加随机的IP,防反爬虫
- 在对方判断出我们时爬虫之后,应该添加更多的headers字段,包括cookie
- cookie的这一块我们可以用session来解决
- 准备一堆的cookie,组成cookie池
- 如果不登陆
- 准备刚开始能够成功请求对方网站的cookie,即接收对方网站设置在response的cookie
- 下一次请求的时候,使用之前的列表中的cookie来请求
- 如果登陆
- 准备多个账号
- 使用程序获取每个账号的cookie
- 之后随机的选择cookie请求登录之后才能访问的网站
- 如果不登陆
- 提取数据
- 确定数据的位置
- 如果数据在当前的url地址中
- 提取的时列表页的数据
- 直接请求列表页url地址,不用进入详情页
- 提取的是详情页的数据
- 1.确定url
- 2.发送请求
- 3.提取数据
- 4.返回
- 提取的时列表页的数据
- 如果数据不在当前的url地址中
- 在其他的响应中,寻找数据的位置
- 1.从network中从上往下找
- 2.使用chrome钟的过滤条件,选择出js,css,img之外的按钮
- 3.使用chrome的search all file,搜索数字和英文
- 在其他的响应中,寻找数据的位置
- 如果数据在当前的url地址中
- 数据的提取
- 确定数据的位置
- 保存
- 保存在本地,text,json,csv
- 保存在数据库
爬虫要根据当前的url地址对应的响应为准,当前url地址的elements的内容和内容和url的响应不一样
页面的数据在那里
- 当前url地址对应的响应中
- 其他的url地址对应的响应中
- 比如ajax请求中
- js生成的
- 部分数据在响应中
- 全部通过js生成
判断请求是否成功
assert response.status_code == 200
url编码
https://tieba.baidu.com/f?kw = \xe6\x9d\x8e\xe6\xaf\x85
字符串格式化的另一种方式
"test{}format".format(1)
使用代理ip
-
准备一对的ip地址,组成ip池,随机选择一个ip来用
-
如何随机选择代理ip,让使用次数少的ip地址有更大的可能性被用到
- {"ip":"ip","times":0}
- [{},{},{}],对这个ip的列表按照使用次数排序
- 选择使用次数少的10个ip,从中随机选择一个
-
检查ip的可用性
- 可以使用requests添加超时参数,判断ip地址的质量
- 在线代理ip质量检测的网站
携带cookie请求
- 携带一堆cookie进行请求,把cookie组成cookie池
使用requests的session对象请求登录之后的网站的思路
- 实例化session
- 先使用session发送请求,登录网站,把cookie保存在session中
- 再使用session请求登录之后才能访问的网站,session能够自动的携带登录成功时保存在其中的cookie,进行请求
不发送post请求,使用cookie获取登录后的页面
- cookie过期时间很长的网站
- 在cookie过期之前能够拿到所有的数据,比较麻烦
- 配合其他程序一起使用,其他程序专门获取cookie,当前程序专门请求页面
字典推导式,列表推导式
cookies="BIDUPSID=3F25DC781B02548A8189297D491A16DD; PSTM=1560840870; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BAIDUID=6E8741147E64571FFFFA7DF44E44AA92:FG=1; BDSFRCVID=bW_OJeC62A5IuP7uPMTjh-bydaMeSM5TH6ao4XCgB-Mx1SpMBEdXEG0Pof8g0KubyKdsogKK3gOTH4PF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tJk8oK0atCI3fn5PqR6OM5JBD2T22-usbPjd2hcH0KLKfpR6Xbro5t-Xhx73e4j2LKjaQ4TnJfb1MRjv3bOrQJDnMxv7QxJibjLDBl5TtUJ6eCnTDMRh-l0QWtOyKMnitKv9-pP2LpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuD6K5j6jWeaus-bbfHJIDoCP8Kb7Vbno5BUnkbfJBD4LtBRQTJ5TT2xb_2T6DJJbpXto6XjL7yajK253v0KvGsl6ytxO28qoHbh7pQT8rhUDOK5OibCr8abbbab3vOIOTXpO1jh8zBN5thURB2DkO-4bCWJ5TMl5jDh3Mb6ksD-FtqtJHKbDHVCL5Jx5; BDUSS=3haUmNJWm5wVGZTfkJRdU51ZVRqRkIxTVBKTndFZ1hsTE1obnhveFRXVW5BUmhmSVFBQUFBJCQAAAAAAAAAAAEAAAD3M-mAt8m457XEzt672tGh1PEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACd08F4ndPBeU; delPer=0; PSINO=6; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1593326774; Hm_lvt_afd111fa62852d1f37001d1f980b6800=1593327266; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; H_PS_PSSID=31907_1461_31325_21117_32139_32046_32092; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; yjs_js_security_passport=a082f5fec3423f5c0b369379442d3581fc8d776d_1593328810_js; __yjsv5_shitong=1.0_7_448adffc4ebfb602d1a695933e08cd93d7b3_300_1593329008410_113.116.115.100_3562e738; Hm_lpvt_afd111fa62852d1f37001d1f980b6800=1593329133; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1593329134"
cookies={i.split("=")[0]:i.split("=")[1] for i in cookies.split("; ")}
[self.url_temp.format(i*50) for i in range(1000)]
获取登录后页面的三种方式
- 实例化session,使用session发送post请求,再使用他获取登录后的页面
- headers中添加cookie
- 在请求方法中添加cookies参数。cookie以字典形式接受
安装第三方模块
- pip install
- 下载源码解码,进入解压后的目录,运行:
python setup.py install
***.whl
安装方法pip install ***.whl
json使用注意点
- json中的字符串都是双引号引起来的
- 如果不是双引号
- eval:能实现简单的字符串和python类型的转化
- replace:把单引号替换为双引号
- 如果不是双引号
正则使用的注意点
re.findall("a(.*?)b","str")
,能够返回括号里的内容,括号前后的字符起到定位和过滤的作用- 原始字符串r
re.findall(r"a(.*?)b","str")
,能够忽略待转译字符串中反斜杠的转译效果 - 点号默认匹配不到
\n
\s
能够匹配到空白字符,不仅包含空格,还有\t|\r\n
xpath学习重点
-
使用xpath helper 或者是Chrome中的copy xpath都是从elements中提取的数量, 但是爬虫获取的是url对应的响应,往往和elements不一样
-
获取文本
a/text()
获取a下的文本a//text()
获取a下的所有标签的文本
-
@符号
a/@href
//ul[@id="detail-list"]
-
//
- 在xpath开始的时候表示从当前html总的任意位置开始选择
p//a
表示的是p下的任何一个a
lxml使用注意点
-
lxml能够修正HTML代码,但是可能会改错
- 使用etree.tostring()观察修改之后的html的样子,根据修改之后的html 字符串写xpath
-
提取页面数据的思路
- 先分组,取到一个包含分组标签的列表
- 遍历,取其中每一组进行数据的提取,不会造成数据的对应错乱