爬虫概念、工具和HTTP
什么是爬虫
- 爬虫就是模拟客户端(游览器)发送网络请求,获取相应,按照规则提取数据的程序。
- 模拟哭护短(浏览器)发送网络请求:照着浏览器发送一模一样的请求,获取和浏览器一模一样的数据。
爬虫的数据的应用
- 呈现出来:展示在网页上,或者是展示在app上
- 进行分析:从数据中寻找一些规律
需要的软件和环境
- 
python3 - 黑马python基础班15天视频
- 基础语法(字符串,列表,字典,判断和循环)
- 函数(函数的创建和调用)
- 面向对象(如何创建一个类,如何使用这个类)
 
 
- 黑马python基础班15天视频
- 
chrome - 分析网络请求用的
 
浏览器的请求
- 
url - 
在chrome中点击检查,点击network 
- 
url = 请求的协议(http)+ 网站的域名 + 资源的路径 + 参数(?开头&隔开) https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&ch=&tn=baiduhome_pg&bar=&wd=abc&rsv_spt=1&oq=abc&rsv_pq=be41b8270005d8a9&rsv_t=79a6Pj%2Fov9dhzgOmd4MC%2FuaI%2BtckdddCpnaH14PJp9ERMVwi8LnwKPeMNppcdVBCvW06&rqlang=cn&rsv_enter=0&rsv_dl=tb 
 
- 
- 
浏览器请求url地址 - 当前url对应的响应+js+css+图片 ----> elements中的内容
 
- 
爬虫请求的url地址 - 当前url对应的响应
 
- 
elements 的内容和爬虫获取到的url地址的响应不同,爬虫中需要以当前url地址对应的响应为准确提取数据 
- 
当前url地址对应的响应在哪儿? - 从network中找到当前的url地址,点击response
- 在页面上右键显示网页源码
 
认识HTTP、HTTPS
- 
HTTP:超文本传输协议 - 以明文的形式传输
 
- 
HTTPS:HTTP + SSL(安全套接字层) - 
传输之前数据先加密,之后解密获取内容 
- 
效率较低,但是安全 
 
- 
- 
Get 请求 和 Post 请求的区别 - 
get请求没有请求体,post有,get请求把数据放到url地址中 
- 
post请求常用登录注册 
- 
post请求携带的数据量比get请求大,多,常用于传输大文本的时候 
 
- 
- 
HTTP协议之请求 - 
请求行 
- 
请求头(Headers) - User-Agent:用户代理:对方服务器能够通过user-agent知道当前请求对方资源的是什么浏览器
- Connnection:Keep-alive:告诉对方我支不支持长连接
- Accept-Encoding:gzip:为了使传输更快,一般会对数据进行压缩
- Accept:text/html;q=0.9,image/web;q=0.8:指定接收的数据类型,q应该概率。
- Accept-language:zh-CN;zh:指定支持语言的优先级
- Cookie:用来存储用户信息,每次请求都会被携带上发送给对方的浏览器。
- 要获取登录后才能访问的页面
- 对方的服务器会通过cookie来判断我们一个爬虫
 
 
- 
请求体 - 携带数据
- get请求没有请求体
- post请求有请求体
 
 
- 
- 
HTTP协议之响应 - 响应头
- 大部分不用注意,只有一个属性set cookie
- Set-Cookie:对方服务器通过该字段设置cookie到本地
- 直接F12 response旁边就是cookie关注两个属性,字典:Name-Value
 
- 大部分不用注意,只有一个属性
- 响应体
 
- 响应头
requests 模块的学习
使用前:安装
- pip install requests
发送get,post请求,获取响应
- 
response = requests.get(url)#发送get请求,请求url地址对应的响应import requests 
 url = "http://www.baidu.com"
 response = requests.get(url)
 print(response) # 返回的是状态码
- 
response = requests.post(url,data={请求字典})#需要多传入一个请求体import requests 
 url="http://fanyi.baidu.com/basetrans"
 query_string={"query":"人生苦短,我用python",
 "from":"zh",
 "tol":"en"}
 response = requests.post(url,data=query_string)
 print(response)
response的方法
- response.text- 该方式往往会出现乱码
- 所以在生成text之前需要先编码一下:response.encoding="utf-8"
 
- response.content- print(response.content())输出的是- b"str"二进制文件
- 把相应的二进制字节流转换为str类型response.content.decode()
 
- 属性
- response.request.url # 发送请求的url地址
- response.url # response相应的url地址
- response.requests.headers # 请求头
- response.headers # 相应请求
 
获取网页源码的正确打开方式
通过下面三种方式一定能够获取到网页的正确解码之后的字符串)
- response.content.decode(默认按照utf-8解码)
- response.content.decode("gbk")
- respnse.text浏览器以猜的方式解码,比较准确
发送带header的请求
即,request headers 请求头中的键值对:为了模拟浏览器,获取和浏览器一模一样的内容。
| headers={ | 
将头信息传入requests模块中:
| response = requests.post(url,data=query,headers = headers) | 
使用超时参数
- requests.get(url,headers,timeout=3) #3 秒内必须返回响应,否则会报错。
retrying 模块的学习
- pip install retrying
- 具体的使用
| from retrying import retry | 
处理Cookie相关的请求
- 
人人网{“email":"mr_mao_hacker@163.com”,“password”:“alarmchime”} 
- 
直接携带cookie请求url地址 - 
cookie 直接放在headers中,传入request headers = {"user-agent": "","Cookie":""} 
- 
requests 语法内单独设置了cookies 传入位置【字典格式】 # 正常cookie 
 cookie = “”
 cookie_dict = {i.split("=")[0]:i.split("=")[1]for i in cookie.split(";")}
 response = requests.get(url,headers = headers,cookies = cookie_dict)
 
- 
- 
先发送post请求,获取cookie,带上cookie请求登录后的页面 - session = requests.session() # session具有的方法和requests一样
- session.post(url,data,headers) #服务器设置在本地的cookie会被存在session
- session.get(url)#会带上之前保存在session中的cookie,能够成功
 import requests 
 session = requests.session()
 # 使用session 发送post请求,获取对方保存在本地的cookie
 post_url = "https://www.wuxiaworld.com/account/login"
 headers = {"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"}
 post_data = {"Email": "2409277719@qq.com",
 "Password": "Wangjiahao526",
 "__RequestVerificationToken":" CfDJ8EwF1hLhM7pChLwkXvZCy55dmm-LnHaweNXreDzH7f9Q3nKbP1PtMCURW_HUeR3CjYSk4tRFYDmihxf89hMNpB9nQbGZgnGve_MMrM6iLfE348bxJv1iFcx_KL4se8y-GnBq-y_KiP6-42Ai2UQ_8U0",
 "RememberMe":"false"}
 response = session.post(post_url,headers=headers,data=post_data)
 # 以上应该能登录成功,成功后登录之前登录不上的个人页面
 url = "https://www.wuxiaworld.com/profile/bookmarks"
 response = session.get(url,headers = headers)
 with open("wuxiaworld3.html","w") as f:
 f.write(response.content.decode())两种方法获取以上的信息 - 
浏览器的element查找,如需要传入关键字"Password"密码 <input type=“password” class=“form-control valid” placeholder=“Password” data-val=“true” data-val-required=“The Password field is required.” id=“Password” name=“Password” aria-describedby=“Password-error” aria-invalid=“false”> 
- 
抓包,记住勾选 [ ]preserved log - 清空后,点击登录按钮,在Network中查找
 
 
⭐️数据提取方法
json格式介绍
- 
数据交换格式,看起来像python类型(列表,字典)的字符串 ![]() 
- 
使用 json之前需要导入json库
- 
哪儿会返回json的数据 - 浏览器切换到手机版
- 抓包app
 
Json语法介绍
json.loads
- 把json字符串转换为python类型
- json.loads(json字符串)
- 完整代码【百度翻译】
json.dumps
- 把python类型转换为json字符串
- json.dumps({"a":"a","b":2})
- json.dumps(ret1,ensure_ascii=False,indent=2))- ensure_ascii:让中文显示成中文
- indent:能够让下一行在上一行的基础上空格
- 推荐使用这个函数,可以控制写入文件的一些参数
 
案例:豆瓣获取美剧分类爬虫案例
手机版可以返回Json格式
- 
如何找内容,同时在Resonse和Preview中查找 黑镜
- 
遇到问题:缺少refer信息,导致的url地址无法访问。 import requests 
 url = ""
 headers = {
 "User-Agent":""
 "Referer":""}
 response = requests.get(url,headers= headers)
 print(response.content.decode())
 json_str = response.content.decode()
 ret1 = json.loads(json_str)#转换为python类型
 print(ret1)
 with open("douban.txt","w",encoding="utf-8") as f:
 f.write(json.dumps(ret1,ensure_ascii=False,indent=2))# indent 能达到换行空两格的效果,因为直接write就是一行内容,ensure_ascii能够直接不以ASCII格式保存字符- 如果url中有callback,没有用可以直接删掉,否则响应不是一个Json格式会报错
 
- 
暂补内容 - 实例化
- def run
- 查询具体url的变化趋势:每次加18以及有个Total值
- 定义 class 可以整理思路
 
Xpath 和 lxml
- 
xpath - 一门从html中提取数据的语言
 
xpath语法
- xpath helper:帮助我们从elements中定位数据【爬虫爬不到这个内容】
- 判断是否定位到相应的属性:多`xh-highlight``
- 
选择节点(标签) html/head/meta:能够选中html下的head下的所有的meta标签
- 
//:能够从任意节点开始选择//li:当前页面上所有的li标签/html/head//link:head下的所有的link标签
- 
@符号的用法
- 选择具体某个元素://div[@class='feed-infinite-wrapper']/ul/li- 选择class='feed-infinite-wrapper’的div下的ul下的li
 
- 选择class='feed-infinite-wrapper’的
- 直接选择某个属性的值:a/@href选择a的href的值
- 
获取文本 - /a/text():a下的标签
- a//text():a下的所有文本,可以选到span中的所有内容
 
- 
当前 - ./a当前节点下的a标签
 
- 
lxml - 
安装: pip install lxml
- 
使用: from lxml import etree 
 element = etree.HTML(“html字符串”)
 element.xpath("")
 
- 
爬虫实例:获取某瓣的标题,url,图片地址,评论数,评分等信息
| import lxml import etree | 
基础知识点的学习
- 
format:字符串格式化的一种方式 "传智{}播客".format(1) 
 "传智{}播客".format([1,2,3])
 "传智{}播客".format({1,2,3})
 "传智{}播客{}".format({1,2,3},[1,2,3])
 "传智{}播客{}".format({1,2,3},1)
- 
列表推导式 - 
帮助我们快速的生成包含一堆数据的列表 [i+10 for i in range(10)]–> [10,11,12,…,19]["10月{}日".format(i) for i in range(1,10)]–>[“10月1日”,“10月2日”,“10月3日”]
 
- 
- 
字典推导式 - 
帮助我们快速的生成包含一堆数据的字典 {i+10:i for i in range(10)} 
 {"a{}".format(i):10 for i in range(3)}
 
- 
- 
三元运算符 - if 后面的条件成立,就把if前面的结果赋值给a,否则把else喂给a
 a = 10 if 4>3 else 20 # a=10 
 a = 10 if 4<3 else 20 # a=20
最终案例
| from lxml import etree | 
写爬虫的讨论
- url
- 知道url地址的规律和总得页码数:构造url地址的列表【没有办法确定】
- start_url:构造法
 
- 发送请求,获取响应
- request
 
- 提取数据
- 返回json字符串:json模块
- 返回的是html字符串:lxml模块配和xpath提取数据
 
- 保存


