requests进阶
1. requests.session()
会话,可以认为是一连串的请求,在这个过程中会保持cookie信息
使用session=requests.session()
创建会话对象,再使用这个对象去发送请求
session发送请求的方式和直接使用requests发送请求方式一样
下面是一个获取17k小说的书架信息的简单案例
import requests
def getbooks17k(data):
# 登录和获取书架的url
url_login = r'https://www.17k.com/ck/user/login'
url_shelf = r'https://user.17k.com/ck/author/shelf?page=1&appKey=2406394919'
# 创建会话对象
session = requests.session()
# 登录获取cookie信息
session.post(url_login, data=data)
# 获取书架信息
resp = session.get(url_shelf)
print(resp.json())
session.close()
if __name__ == '__main__':
data = {
"loginName": '', # 账号
"password": '' # 密码
}
getbooks17k(data)
当然,你也可以直接把cookie直接封装到requests请求里
2. 防盗链
在对有些网站发送请求时,服务器会对请求做一些检查,来判断是否是通过浏览器正常访问的
一种简单的方式就是通过请求头携带参数Referer
,该参数是一个页面链接,表示你是由哪个页面跳转来的。如果在请求时不携带这个参数或者携带了错误的参数值,服务器就可以识别出你是爬虫,从而拒绝访问。
具体的参数构成可以通过浏览器抓包工具去解析,对于js加密可能需要掌握一点js去分析页面源代码。
下面是一个获取梨视频排行榜的简单案例
import random
import requests
from bs4 import BeautifulSoup
def getvideo():
# 页面url
url = 'https://www.pearvideo.com/popular'
resp = requests.get(url)
# 使用bs4解析页面,获取每个视频的a标签
soup = BeautifulSoup(resp.text, "html.parser")
a_list = soup.find_all(lambda tag: tag.name == "a" and tag.get("class") == ["actplay"])
urls = []
for _, a in enumerate(a_list, 1):
# 这个网站使用了js来动态加载video标签,所以我们无法从源代码获取视频链接
# 通过抓包工具不难发现,在点击a标签跳转后,会向https://www.pearvideo.com/videoStatus.jsp发送请求获取到视频的url
# 而参数contId是详情页面的url的一部分,mrd通过检查js代码发现只是随机数,不用管
# 视频id
id = a.get("href").split("_")[1]
# 视频详情页url,用作防盗链参数
url = f"https://www.pearvideo.com/{a.get('href')}"
# 真正获取数据的url
videoStatus = f"https://www.pearvideo.com/videoStatus.jsp?contId={a.get('href').split('_')[1]}&mrd={random.random()}"
# 准备好数据我们就开始了
# 向videoStatus发送请求,注意在headers字段加入"Referer": url
# 不加不会报错,但是获取不到数据
resp = requests.get(videoStatus, headers={
"User-Agent": "Mozilla/5.0",
"Referer": url
})
# 获取到json格式数据,发现获取到的url和实际的url(通过浏览器开发者工具查看渲染后的页面)有所区别
# 比对后发现,是把srcUrl中与systemTime相同的部分换成了"cont-{id}",之前获取的id就用到这里
s = resp.json()['systemTime']
data = resp.json()['videoInfo']['videos']['srcUrl'].replace(s, f"cont-{id}")
print(_, data)
urls.append(data + "\n")
with open("urls.txt", "wt", encoding="utf_8") as f:
f.writelines(urls)
if __name__ == '__main__':
getvideo()
3. 代理
如果我们在短时间内向服务器发送大量请求,那么服务器就可能会把你加入黑名单,你就无法再访问这个网站。
所以对于大批量,高并发的请求,我们就需要用到代理。
在一般学习过程和编写一些小型爬虫时,我们一般是不需要使用代理的,也不推荐使用
,所以只做了解。
简而言之,代理就是利用别的客户端向服务器发送请求,这样,服务器看到的就是别的客户端
import requests
# 直接请求
requests.get("https://baidu.com")
# 使用代理
proxies = {
"https": "代理ip",
"http": "代理ip"
}
# 只是添加了一个参数而已
requests.get("https://baidu.com", proxies=proxies)
2023.3.20