1.浏览器的问题
Elements: 里面的东西是你的页面源代码 -> JavaScript -> 浏览器的二次渲染(table,或其他标签) -> elements里面的代码
request.get(url)拿到的只是页面源代码
Console:控制台,这里面可以写js代码
Sources:放着页面源代码和网页的所有资源,后期会作为我们调试js的最好用的地方
Network:
headers:
User-Agent:请求的设备版本,以后所有的请求至少给一个这个东西(APP自行判断)
Referer:防盗链,在抓包工具中,双击url,如果能获取到你需要的东西,就不需要加Referer(get可以,post不行)
payload:请求参数(get,post)
Application:
cookies:可以清空cookie信息,方便我们抓包
无痕模式:
没有一些缓存来干扰你
2.requests -> 发请求专用
get请求
Query String Parameters
1.把参数通过url进行传递
url = "https://www.baidu.com/s?name=alex&hobby=sb"
2.通过params传递参数
url = "https://www.baidu.com/s"
dict = {
"name": "alex",
"hobby": "sb",
}
request.get(url, params=dict)
上述参数最终在发送时,参数都会加到url上
post请求
下面这两个不会同时出现
Form Data,直接给字典即可
url = "普通的url"
data = {
"loginName": "14252",
"password": "11111",
}
requests.post(url=url, data=data)
Request Payload
请求挂载,传输的数据大多数情况下是json字符串
在payload里面可以观察到json格式的数据或者在请求头里面可以看到
Content-Type:application/json
application/x-www-form-urlencoded 默认
1.可以通过data传递数据
import json
url = "普通的url"
data = {
"loginName": "14252",
"password": "11111",
}
# separators=(",", ":")防止json转换的时候有空格的干扰
requests.post(url=url, data = json.dumps(data, separators=(",", ":")), headers={'Content-Type':'application/json'})
2.可以直接使用requests里面的json来自动处理
url = "普通的url"
data = {
"loginName": "14252",
"password": "11111",
}
requests.post(url=url, json=data) # 比较方便,但是有坑
坑:python自动进行字典转换成json的时候会有空格,服务器那边很有可能会判断这个空格
3.混合
url = "普通的url"
params={
csrf-token:""
}
data = {
params:"xxx",
encSecKey:"xxx",
}
requests.post(url,params=params,data=data)
如果你在protocol里面看到h2的时候,表示当前这个请求用的是http2.0的版本。
大多数网页是兼容http1.1的,有些网站会屏蔽http1.1
python的requests这个模块不支持http2.0
你用你能使用的所有手段都测试过了,发现还是不行,可以考虑用一下http2来请求
python发送http2的请求:pip install httpx
import httpx
client = httpx.Client(http2=True)
client.get()
client.post()
# 剩下的和requests一样
请求头:
UA:一定要给的
Referer:看情况给
Cookie:可以直接从浏览器复制过来
加载有两种情况:
1.在响应头里 Set-Cookie
我们需要实现浏览器相同的功能
浏览器接受到的cookie会在后续的请求中自动代入
咱们的程序也需要实现相同的功能
(1)在每次请求url的时候,手工记录cookie的信息
dic = resp.cookies.get_dict() 获取到响应的cookie字典
可以对dic进行随意的操作
# 再次发送请求时,把cookie带上
requests.get(url, cookies=cookiejar_from_dict(dic))
(2)用session自动来帮你维护cookie
session对象中保存的请求头和cookie信息会共享
上一次请求用的请求头和set-cookie进来的东西会自动增加给下一次请求,免去我们手工维护的麻烦
以后写请求都用session
2.通过js来动态写入cookie(需要手工去维护)
js可以通过document.cookie = xxxx来重新写入cookie信息
服务器返回一个初始化的数字:123456
js:
拿到123456
进行md5计算
把md5值存入cookie
以后请求的时候,就会带着这个md5值给服务器
你的爬虫,想要正确的结果:
服务器返回一个初始化的数字:123456
python:
拿到123456
进行md5计算
把md5值存入cookie
以后请求的时候,就会带着这个md5值给服务器
3.数据解析
返回数据
1. html
resp = session.get()
page_source = resp.text
解析html:
1.如果你需要的数据在script里面
html里面的script中提取需要的内容,最好的方案是re,没有之一
正则三要素:开头,结尾,.*?
re.compile(r'url: "(?P<url>.*?)",')
2.正常的标签中
bs4 -> 在处理非标准html的时候。例如xml,svg,自定义标签,属性
find(标签,属性=值)
findall(标签,属性=值)
xpath -> html好用
/
// 任意
. 当前
div/span/text()
div[@class='周杰伦']
div[last()]
div/span/@href
2. js代码
jsonp:js代码+数据
xxxx({数据})
obj = re.compile(r'\((?P<data>.*)\)')
3. png,jpg土木,m3u8,mp4等等
4. css样式文件 -> 直接保存即可
5. 字体文件 -> 直接保存即可
6. json数据
resp = session.get()
print(resp.text) # 先看一眼你获取到的东西是不是json格式
dic = resp.json() # 服务器返回的东西必须是json格式才可以
7. 其他.....
各种加密的数据,看着它的js怎么解密的,我们就怎么做
4.数据的存储
print(???) # 这玩意儿不用过分纠结
msg = "xxxx"
print(msg) # 打印这个东西报错了,gbk不能解析\xxxxx
解决方案:
1.不打印了,直接文件输出
2.处理编码问题
msg = msg.encode("gbk", "ignore").decode("gbk", "ignore")
不作为最终给客户的结果
1.csv,excel -> 存储数据,一条一条的表格形式的数据
我们首选csv,csv的本质是纯文本,可以像处理txt一样去处理csv
如果客户非要excel,先存储csv,然后用pandas将csv搞成excel
2. mysql
sql语句:操作数据库中的数据
1. insert into 表(字段1, 字段2, 字段3...) values ('值1', '值2', '值3'...)
2. select * from 表 -> 检测是否插入ok,数据是否没问题
3. delete from 表 where 条件 -> 删除之前的数据
4. update 表 set 字段 = 值, 字段 = 值... where 条件
python怎么办?
pymysql -> 看代码
3.mongo
db.collection.insert({数据})
新版本的mongo
db.collection.insert_one({数据})
db.collection.insert_many([{},{},{}])
db.collection.find({})
4.redis 很少会直接向redis中存储数据,redis主要做缓存
5.普通文件,正常下载即可
如何提高爬虫效率
1.多线程 -> 简单,并发可控
直接上线程池,控制好并发
相似或者相同的任务适合用多线程
2.多进程
你的多个任务之间没有多大关联的时候
进程是一个资源单位,在内存中开辟一个独立的空间
3.协程(慎用)
电影:m3u8 -> 一堆url -> 下载文件 -> 云服务(七牛云,各种云),为了用户看着流畅,一般是不设防的
不设防,没有访问频率限制的场景下可以使用
爬虫框架-scrapy -> 干活不会首选,但框架设计思路比较好
调度器 -> 1.去除重复请求 2.请求队列