三:《智慧的网络爬虫》— 网络请求模块(下)

简介: 本篇文章讲解了网络请求模块中Requests模块的get请求和post请求,并用十几张图示详细介绍了爬虫工具库与开发者工具的操作与使用;同时本篇文章也列举了多个代码示例如:对搜狗网页的爬取;爬取360翻译(中英文互译程序)并以此介绍了重放请求(通过重放请求来确定反爬参数)以及Cookie与Session实战案例 -- 爬取12306查票
1.Requests模块:

Requests是用Python语言编写,基于urllib,采用 Apache2 Licensed开源协议的 HTTP 库,它比urllib更加的方便,可以节约我们大量的工作,完全满足 HTTP 测试需求

Requests的哲学是以 PEP 20(一种标准规范)的习语为中心开发的,所以它比urllib更加简洁

(1)Requests模块的安装:

Requests是Python语言的第三方库,专门用于发送HTTP请求

安装方式:

#1.在终端输入
pip install requests
#2.换源安装:若出现下载超时,过慢的情况,换源即可

# 示例
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/

# 阿里云 http://mirrors.aliyun.com/pypi/simple/
# 豆瓣http://pypi.douban.com/simple/
# 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
# 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
# 华中科技大学http://pypi.hustunique.com/

(2)Requests的使用:

1.常用方法:

requests.get("网址")

request.post("网址")

2.常用参数:

urlurl地址,接口文档标注的接口请求地址

params:请求数据中的链接,常见的一个get请求,请求参数都是在url地址中

data:请求数据,参数是表单的数据格式

json:接口常见的数据请求格式

headers:请求头信息

cookie:保存的用户登录信息,比如做一些充值功能,但是需要用户已经登录,需要cookie信息的请求信息传输

#推荐一个爬虫工具:爬虫工具库
# https://spidertools.cn/#/curl2Request

3.响应内容:

r.encoding:获取当前的编码

r.encoding = 'charset':设置编码格式,多为'utf-8'编码

r.text:以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字体编码进行解码

r.cookies:返回cookie

r.headers:请求头,以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None

r.status_code:响应状态码

r.json()Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛出异常

r.content:字节流,以字节形式(二进制)返回,字节方式的响应体,会自动为你解码gzipdeflate压缩

4.Requestsget请求之参数应用 -- 搜狗搜索海贼王案例:

(1)把参数添加到url链接中 -- 平民写法(用到的最多的写法)

#导入模块
import requests

#目标url
url = 'https://www.sogou.com/web?query=%E6%B5%B7%E8%B4%BC%E7%8E%8B&_asf=www.sogou.com&_ast=&w=01015002&p=40040108&ie=utf8&from=index-nologin&s_from=index&oq=&ri=0&sourceid=sugg&suguuid=&sut=0&sst0=1678439364372&lkt=0%2C0%2C0&sugsuv=1666847250696567&sugtime=1678439364372'

#请求头部信息
headers = {
   
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
    'Cookie':'ABTEST=8|1701776265|v17; SNUID=7B0346FA646568A5CDB26F5B64A6691E; IPLOC=CN3205; SUID=186722991B5B8C0A00000000656F0B89; cuid=AAFqAmPwSAAAAAqMFCnulgEASQU=; SUV=1701776266958330; browerV=3; osV=1; sst0=372'

}

#发起请求
response = requests.get(url, headers=headers)

#指定编码格式
response.encoding = 'utf-8'

#获取响应
html = response.text

#文件写入响应数据内容
with open("海贼王1.html","w",encoding='utf-8') as i:
    i.write(html)

#打印响应(数据)内容
print(html)

注意: 1.值与值之间需要用逗号隔开

(2)把参数添加到params中 -- 官方写法(不常用)

#导入模块
import requests

#请求头部信息 -- 字典的形式
headers = {
   
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
    #cookie的两种设置方式
    #(1)'Cookie':'ABTEST=8|1701776265|v17; SNUID=7B0346FA646568A5CDB26F5B64A6691E; IPLOC=CN3205; SUID=186722991B5B8C0A00000000656F0B89; cuid=AAFqAmPwSAAAAAqMFCnulgEASQU=; SUV=1701776266958330; browerV=3; osV=1; sst0=372'
}

#cookie值 -- (2)字典的形式
cookies = {
   
    "ABTEST": "8^|1701776265^|v17",
    "SNUID": "7B0346FA646568A5CDB26F5B64A6691E",
    "IPLOC": "CN3205",
    "SUID": "186722991B5B8C0A00000000656F0B89",
    "cuid": "AAFqAmPwSAAAAAqMFCnulgEASQU=",
    "SUV": "1701776266958330",
    "browerV": "3",
    "osV": "1",
    "sst0": "372"
}

#目标url
url = "https://www.sogou.com/web"

#get请求所携带的参数
params = {
   
    "query": "海贼王",
    "_asf": "www.sogou.com",
    "_ast": "",
    "w": "01015002",
    "p": "40040108",
    "ie": "utf8",
    "from": "index-nologin",
    "s_from": "index",
    "oq": "",
    "ri": "0",
    "sourceid": "sugg",
    "suguuid": "",
    "sut": "0",
    "sst0": "1678439364372",
    "lkt": "0^%^2C0^%^2C0",
    "sugsuv": "1666847250696567",
    "sugtime": "1678439364372"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params) #因为cookie中不只有一个键值对所以要加s

print(response.text)
print(response)

#文件写入响应数据内容
with open("海贼王2.html","w",encoding='utf-8') as i:
    i.write(response.text)

官方写法快速的写法:

1.进入目标url的页面进行如下操作:

官方写法1.png

>

2.进入爬虫工具库进行如下操作:

官方写法2.png

>

3.得到如下代码:

import requests

headers = {
    
 "authority": "www.sogou.com",
 "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
 "accept-language": "zh-CN,zh;q=0.9",
 "cache-control": "max-age=0",
 "sec-ch-ua": "^\\^Google",
 "sec-ch-ua-mobile": "?0",
 "sec-ch-ua-platform": "^\\^Windows^^",
 "sec-fetch-dest": "document",
 "sec-fetch-mode": "navigate",
 "sec-fetch-site": "none",
 "sec-fetch-user": "?1",
 "upgrade-insecure-requests": "1",
 "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}
cookies = {
    
 "ABTEST": "8^|1701776265^|v17",
 "SNUID": "7B0346FA646568A5CDB26F5B64A6691E",
 "IPLOC": "CN3205",
 "SUID": "186722991B5B8C0A00000000656F0B89",
 "cuid": "AAFqAmPwSAAAAAqMFCnulgEASQU=",
 "SUV": "1701776266958330",
 "browerV": "3",
 "osV": "1",
 "sst0": "372"
}
url = "https://www.sogou.com/web"
params = {
    
 "query": "^%^E6^%^B5^%^B7^%^E8^%^B4^%^BC^%^E7^%^8E^%^8B",
 "_asf": "www.sogou.com",
 "_ast": "",
 "w": "01015002",
 "p": "40040108",
 "ie": "utf8",
 "from": "index-nologin",
 "s_from": "index",
 "oq": "",
 "ri": "0",
 "sourceid": "sugg",
 "suguuid": "",
 "sut": "0",
 "sst0": "1678439364372",
 "lkt": "0^%^2C0^%^2C0",
 "sugsuv": "1666847250696567",
 "sugtime": "1678439364372"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)

print(response.text)
print(response)

注意: 1.官方写法不建议使用,因为它会把所有的参数都携带上,有些参数可能会有反爬

​ 2.params的数据类型为字典数据,必须满足键值对

5.如何快速将headers中的参数匹配为字典数据(了解):

#使用正则替换
1.将 headers 中的参数内容全部选中
2.按住 CTRL + R 键:会弹出一个提示框
3.在第一行输入正则语法:(.*):\s(.*)$
4.在第二行输入正则语法:"$1":"$2",
5.勾选 regax
6.点击 Replace All

注意: 1.因为已经有爬虫工具库了,所以这个方法也就用不上了,大家当作拓展就好

​ 2.写的时候注意语法不要写错,特别是第二行的正则语法后面的英文逗号,一定要加

正则替换法的操作图示:

正则替换法操作图示1.png

>

正则替换法操作图示2.png

6.Requestspost请求:

post请求的大多数用法和get请求一样,只是需要加上data参数

post方法的使用场景:

​ 1.网页需要登录的情况下

​ 2.需要给网页传输内容的情况下

语法格式:

response = requests.post("网址", data = data,headers=headers)

360翻译示例:

#导入模块
import requests

#目标url
'''
url分析 -- 实现英文翻译成中文:
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=love
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=like
https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=enjoy
根据多个英文翻译的url分析,发现改变的只有单词不同,其余的内容完全一致,也就是说我们可以把最后面单词的位置设置成一个变量,这样的话就可以实现单词翻译,
而不是想翻译一个单词就去改变一下它的url
'''

'''
url分析 -- 实现中文翻译成英文:
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E7%88%B1%E6%83%85
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E5%96%9C%E6%AC%A2
https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E4%BA%AB%E5%8F%97
'''

'''
根据两种翻译的url分析,发现除结尾不同外其eng也不同,一个是0;一个是1
两种方法都实现的实现方法: 
第一个方法: if判断
第二个方法: 函数
'''

print("中文 --> 英文 ; 点击0")
print("英文 --> 中文 ; 点击1")
choose = input("请输入你的选择: ")
word = input("请输入你想翻译的内容: ")
url = f'https://fanyi.so.com/index/search?eng={choose}&validate=&ignore_trans=0&query={word}'

#请求头信息
headers = {
   
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
    'Pro':'fanyi'  # 查看后发现在这个参数中做了反爬,所以这个参数必须要加上
}

#post请求要携带的参数
data = {
   
    'eng': f'{choose}',  # 注意改变参数,因为url中的eng参数已经被我们设置成了choose变量
    'validate': "",
    'ignore_trans': '0',
    'query': f'{word}'  # 注意改变参数,因为url中的最后一项参数已经被我们设置成了word变量
}

#发起请求
response = requests.post(url,headers = headers,data = data)

'''
#检测可能出现的错误
print(response.text) #经过检测后发现没有报错,data不可能有问题,所以只能是在其它地方出现反爬
'''

'''
#获取响应数据
result = response.json() #报出 JSONDecodeError 错误,说明response并不能满足转换成json对象
print(result)
'''

'''
#获取响应数据
result = response.json()
print(result)
'''
#获取响应数据
result = response.json()

#信息过滤
fanyi = result['data']['fanyi'] #字典取值

'''
字典取值的两种方法:
    1.['key'] -- 取不到值会报错【
    2.xxx.get('key') -- 取不到值会返回None

        注意:一旦取不到值对于第一种方法需要进行异常处理,而第二种方法则不用去管
'''
print(fanyi)

信息过滤图示:

信息过滤图示1.png

信息过滤图示2.png

信息过滤图示3.png

重放请求:(以360翻译为示例进行图示讲解)

通过重放请求来寻找反爬参数:

(1)

重放(1).png

(2)

重放(2).png

(3)

重放(3).png

(4)

重放(4).png

(5)

重放(5).png

(6)

重放(6).png

(7)

重放(7).png

注意:

当删除的是非反爬参数时,我们会发现它并不影响正常的运行,所以只有删除的是反爬参数的时候,才会影响到正常的运行

2.CookieSession实战:

​ 在浏览网站的过程中,我们经常会遇到需要登录的情况,有些页面只有登录之后才可以访问。在登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且在很长时间内都不会失效,这里面所涉及的就是 SessionCookie 的相关知识

(1)Cookie

​ 通过在客户端记录的信息确定用户身份

​ HTTP是一种无连接协议,客户端和服务器交互仅仅限于请求 / 响应过程,结束后断开,下一次请求时,服务器会认为是一个新的客户端,为了维护他们之间的连接,让服务器知道这是前一个用户发起的请求,就必须在一个地方保存客户端信息

(2)Session

Session,中文称之为会话,通过在服务端记录的信息确定用户身份,其本义是指有始有终的一系列动作。例如打电话时,从拿起电话拨号到挂断电话之间的一系列过程就可以称为一个 Session

爬虫图解CookieSession -- 登录流程:

登录流程.png

文字解析:

​ 1.再次登录其实就是验证之前生成的账号和密码,从数据库中去查询当前的用户是否存在,若存在就是登录成功了,然后通过加密算法返回session_id
​ 2.set_cookie是服务器返回的,因为只有服务器返回的才是set_cookie

​ 3.服务端根据cookie中携带的session_id去名为session的数据库(假设session_id存储在名为session的数据库中)中找session_id是否存在

​ 4.这样做的好处就是用户只需要输入一次账号和密码,之后在访问网页时,只需要在headers信息利用Cookie包含session_id,后台就可以根据session_id来判断用户是否登录

Cookie与Session实战案例 -- 12306查票示例:

import requests

headers = {
   
    "Accept": "*/*",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Cache-Control": "no-cache",
    "Connection": "keep-alive",
    "If-Modified-Since": "0",
    "Pragma": "no-cache",
    "Referer": "https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest",
    "sec-ch-ua": "^\\^Google",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "^\\^Windows^^"
}
cookies = {
   
    "_uab_collina": "170210568210505922888592",
    "JSESSIONID": "749E316CAE2341138F39924F8E156F25",
    "_jc_save_fromStation": "%u5317%u4EAC%2CBJP",
    "_jc_save_wfdc_flag": "dc",
    "BIGipServerotn": "3788964106.64545.0000",
    "BIGipServerpassport": "837288202.50215.0000",
    "guidesStatus": "off",
    "highContrastMode": "defaltMode",
    "cursorStatus": "off",
    "route": "495c805987d0f5c8c84b14f60212447d",
    "_jc_save_fromDate": "2024-06-26",
    "_jc_save_toDate": "2024-06-26",
    "_jc_save_toStation": "%u6210%u90FD%2CCDW"
}
url = "https://kyfw.12306.cn/otn/leftTicket/query"
params = {
   
    "leftTicketDTO.train_date": "2024-06-26",
    "leftTicketDTO.from_station": "BJP",
    "leftTicketDTO.to_station": "CDW",
    "purpose_codes": "ADULT"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)

data = response.json()
# print(data,type(data))

result = data['data']['result']
# print(result,type(result))

for item in result: # item代表每一个车次数据
    # print(item,"此时是字符串")
    data_li = item.split('|') # 代表每一车次的杂乱数据
    # print(data_li,"此时是列表")
    # for i,f in enumerate(data_li): # 这个for循环是为了确定一等做和车次的索引
    #     pass
    #     print(i,f) # 通过 '|' 分割,拿到每一个杂乱小数据的索引值与具体的值

    '''
    车次 -- 索引为3
    一等座 -- 索引为31
    '''

    if data_li[31] != "无" and data_li[31] != "":
        print(data_li[3], "有票", "一等座剩余:", data_li[31])
    else:
        print(data_li[3], "无票")

注意: 代码失效可能是因为cookiesurlparams等需要更新替换

目录
相关文章
|
1月前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
2月前
|
移动开发 网络协议 NoSQL
不为人知的网络编程(十七):冰山之下,一次网络请求背后的技术秘密
本文将抛弃千篇一律的计网知识理论,从现实的互联网技术实践角度,一步步为你分享一次网络请求背后的技术秘密。
59 0
|
2月前
|
消息中间件 监控 网络协议
Python中的Socket魔法:如何利用socket模块构建强大的网络通信
本文介绍了Python的`socket`模块,讲解了其基本概念、语法和使用方法。通过简单的TCP服务器和客户端示例,展示了如何创建、绑定、监听、接受连接及发送/接收数据。进一步探讨了多用户聊天室的实现,并介绍了非阻塞IO和多路复用技术以提高并发处理能力。最后,讨论了`socket`模块在现代网络编程中的应用及其与其他通信方式的关系。
244 3
|
3月前
|
数据采集 Web App开发 开发工具
|
3月前
|
数据安全/隐私保护
|
3月前
|
数据采集 API 开发者
🚀告别网络爬虫小白!urllib与requests联手,Python网络请求实战全攻略
在网络的广阔世界里,Python凭借其简洁的语法和强大的库支持,成为开发网络爬虫的首选语言。本文将通过实战案例,带你探索urllib和requests两大神器的魅力。urllib作为Python内置库,虽API稍显繁琐,但有助于理解HTTP请求本质;requests则简化了请求流程,使开发者更专注于业务逻辑。从基本的网页内容抓取到处理Cookies与Session,我们将逐一剖析,助你从爬虫新手成长为高手。
76 1
|
2月前
|
JSON API 开发者
深入解析Python网络编程与Web开发:urllib、requests和http模块的功能、用法及在构建现代网络应用中的关键作用
深入解析Python网络编程与Web开发:urllib、requests和http模块的功能、用法及在构建现代网络应用中的关键作用
22 0
|
4月前
|
数据采集 机器学习/深度学习 人工智能
Python爬虫入门指南探索AI的无限可能:深度学习与神经网络的魅力
【8月更文挑战第27天】本文将带你走进Python爬虫的世界,从基础的爬虫概念到实战操作,你将学会如何利用Python进行网页数据的抓取。我们将一起探索requests库和BeautifulSoup库的使用,以及反爬策略的应对方法。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你打开一扇通往数据抓取世界的大门。
|
4月前
|
JSON API 数据格式
Python网络编程:HTTP请求(requests模块)
在现代编程中,HTTP请求几乎无处不在。无论是数据抓取、API调用还是与远程服务器进行交互,HTTP请求都是不可或缺的一部分。在Python中,requests模块被广泛认为是发送HTTP请求的最简便和强大的工具之一。本文将详细介绍requests模块的功能,并通过一个综合示例展示其应用。
101 11
下一篇
DataWorks