鱼C论坛

 找回密码
 立即注册
查看: 473|回复: 3

[技术交流] Urllib和Requests库实现同样功能的Get和Post比较

[复制链接]
发表于 2024-5-29 05:59:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 591821661 于 2024-5-29 06:13 编辑

起因是在写爬虫的时候还在Urllib库和Requests库之间纠结。于是心血来潮抓包比较一下两个库的区别。
目前使用Urllib库的主要原因是因为它可以全局共享一个Cookie池,优点是属于原生自带的库,但是写法上要比Requests多很多繁琐的步骤。

Snipaste_2024-05-29_05-54-29.png
Connection: keep-alive:保持连接打开,可以提高性能和效率,适合频繁请求的场景。
Connection: close:在每个请求后关闭连接,简化连接管理,适合单次请求的场景。
Snipaste_2024-05-29_06-12-49.png
可以看到库的维护者把这个事情列成了TODO项(待做)
Snipaste_2024-05-29_06-10-38.png
Accept: */* 当客户端对返回的数据类型没有特定要求时,可以使用 Accept: */*。这通常用于浏览器和一些 HTTP 客户端库的默认设置,确保客户端不会因为不支持某种特定类型而无法处理响应。

Accept-Encoding: identity 即告诉服务器希望接收未经压缩的响应数据
大多数现代浏览器和 HTTP 客户端会自动处理各种内容编码方式,并默认支持压缩编码(如 gzip, deflate 等)。因此,显式使用 Accept-Encoding: identity 的场景比较少见,通常用于调试或在特定情况下需要获取未经压缩的响应数据时。

  1. import urllib
  2. import urllib.request
  3. import http.cookiejar
  4. import json
  5. import socket
  6. import requests

  7. # Fiddle 抓包软件 Tool -> Fiddler Options -> Connections -> Listening port 7777
  8. proxy = '127.0.0.1:7777'

  9. def cake_init(cookies_filename="cookies.txt", UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 HBPC/11.0.6.301', proxy='127.0.0.1:7777'):
  10.     socket.setdefaulttimeout(60) # 设置60秒超时
  11.     proxy_support = urllib.request.ProxyHandler({'http':proxy,'https':proxy}) if proxy else urllib.request.ProxyHandler({})
  12.     cookiejar = http.cookiejar.MozillaCookieJar(cookies_filename) # 加载cookies内容 cookiejar.save()能够保存文件
  13.     cookie_support = urllib.request.HTTPCookieProcessor(cookiejar)
  14.     opener = urllib.request.build_opener(proxy_support,cookie_support)# urllib钢铁侠组配
  15.     opener.addheaders = [
  16.                          ('User-agent', UA),
  17.                          ('Accept', '*/*'),
  18.                          # ('referer', "https://www.douyin.com/"),
  19.                          # ('authority', 'www.douyin.com'),
  20.                          ('Accept-Encoding','gzip, deflate'), # 默认是identity即告诉服务器希望接收未经压缩的响应数据
  21.                          ]
  22.     urllib.request.install_opener(opener) #urllib钢铁侠开机初始化
  23.     return cookiejar

  24. def getjson(url):
  25.     response  = urllib.request.urlopen(url)
  26.     data_json = json.loads(response.read())
  27.     return data_json

  28. def getjson_post(url,data):
  29.     req       = urllib.request.Request(url)
  30.    
  31.     # Post的数据类型选择
  32.     # data_coded = urllib.parse.urlencode(data).encode('utf-8')
  33.     # req.add_header('Content-Type', 'application/x-www-form-urlencoded')
  34.    
  35.     # 提交Json要改变默认的Content-Type类型
  36.     data_coded = json.dumps(data).encode('utf-8')
  37.     req.add_header('Content-Type', 'application/json; charset=utf-8')
  38.     # 如果需要对单个请求进行进一步客制化 其中的urlopen()还需要生成request实例进行自定义。
  39.     response  = urllib.request.urlopen(req,data_coded)
  40.     data_json = json.loads(response.read())
  41.     return data_json

  42. def getjson_header(url,header_dict):
  43.     # header_list = [('User-agent', UA),]
  44.     req  = urllib.request.Request(url)
  45.     for key in header_dict:
  46.         req.add_header(key, header_dict[key])
  47.     response  = urllib.request.urlopen(req)
  48.     data_json = json.loads(response.read())
  49.     return data_json

  50. # 初始化容器,使其能够保存Cookies,
  51. cookiejar = cake_init(proxy=proxy)
  52. # cookiejar.save()

  53. ip_api_url = 'http://ip-api.com/json/?fields=61439'

  54. data = {'a':1,'b':2}
  55. # 对跨站检测有用,防止视频链接被其他网站直接调用,会检测视频来源
  56. header_dict = {'Referer':'https://www.douyin.com/'}

  57. s_get_dict = getjson(ip_api_url)
  58. s_get_dict = getjson_post(ip_api_url,data)
  59. s_get_dict = getjson_header(ip_api_url,header_dict)

  60. response = requests.get(ip_api_url,proxies={'https':proxy})
  61. response = requests.post(ip_api_url,json=data,proxies={'https':proxy})
  62. res_json = response.json()

  63. print('----------------------IP Information Begin--------------------------')
  64. for key in s_get_dict:
  65.     print('%s : %s' % (key, s_get_dict[key]))
  66. print('----------------------IP Information End--------------------------\n')


  67. print('----------------------IP Information Begin--------------------------')
  68. for key in res_json:
  69.     print('%s : %s' % (key, res_json[key]))
  70. print('----------------------IP Information End--------------------------\n')
复制代码

分别使用Fiddler的抓包方法

1.png 2.png 4.png 5.png

总结: Requests库更加简洁,封装的也更加全面。
3.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-5-29 06:00:02 | 显示全部楼层
在Python中,我们可以使用urllib库和requests库来发送HTTP请求,实现GET和POST功能。这两个库都可以实现相同的功能,但在使用上有一些差异。

首先,我们来看一下使用urllib库实现GET请求的代码:

  1. import urllib.request

  2. # 发送GET请求
  3. response = urllib.request.urlopen(url)
  4. html = response.read()
  5. print(html)
复制代码


使用urllib库时,我们需要先导入`urllib.request`模块,然后使用`urlopen()`函数发送GET请求,接着使用`read()`方法读取响应内容。

接下来,让我们来看一下使用urllib库实现POST请求的代码:

  1. import urllib.request
  2. import urllib.parse

  3. # 构造请求数据
  4. data = {'key1': 'value1', 'key2': 'value2'}
  5. data = urllib.parse.urlencode(data).encode('utf-8')

  6. # 发送POST请求
  7. req = urllib.request.Request(url, data=data, method='POST')
  8. response = urllib.request.urlopen(req)
  9. html = response.read()
  10. print(html)
复制代码


使用urllib库发送POST请求时,我们需要使用`urllib.parse.urlencode()`函数将请求参数编码为URL格式,并使用`encode()`方法将其转换为字节流。然后,我们使用`urllib.request.Request()`构造一个请求对象,通过设置`method`参数为'POST',并传入请求数据,再通过`urlopen()`函数发送请求。

接下来,让我们看一下使用requests库实现相同功能的代码:

  1. import requests

  2. # 发送GET请求
  3. response = requests.get(url)
  4. html = response.text
  5. print(html)
复制代码


使用requests库时,我们只需要导入`requests`模块,使用`get()`函数发送GET请求,然后使用`text`属性获取响应内容。

再来看看使用requests库实现POST请求的代码:

  1. import requests

  2. # 构造请求数据
  3. data = {'key1': 'value1', 'key2': 'value2'}

  4. # 发送POST请求
  5. response = requests.post(url, data=data)
  6. html = response.text
  7. print(html)
复制代码


使用requests库发送POST请求时,我们只需要使用`post()`函数,并传入请求参数即可。

从上面的例子可以看出,使用requests库相比urllib库更加简洁和方便。requests库封装了更多的功能,如自动处理cookie,更友好的错误提示等。因此,如果可以选择,我建议使用requests库来发送HTTP请求。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-5-29 06:16:05 | 显示全部楼层
如果要运行代码的话,第十行把Proxy设置为空字符串
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-5-29 06:16:37 | 显示全部楼层
591821661 发表于 2024-05-29 06:16
如果要运行代码的话,第十行把Proxy设置为空字符串


如果你想要运行代码,请确保你已经安装了所需的库,并将第十行的proxy参数设置为空字符串。这样代码中的发送请求部分将会使用默认的网络设置,而不是通过代理服务器发送请求。

代码示例:

  1. import urllib.request
  2. import urllib.parse
  3. import http.cookiejar
  4. import json
  5. import socket
  6. import requests

  7. # Fiddle 抓包软件 Tool -> Fiddler Options -> Connections -> Listening port 8888
  8. proxy = ''

  9. def cake_init(cookies_filename="cookies.txt", UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 HBPC/11.0.6.301', proxy=''):
  10.     socket.setdefaulttimeout(60) # 设置60秒超时
  11.     proxy_support = urllib.request.ProxyHandler({'http':proxy,'https':proxy}) if proxy else urllib.request.ProxyHandler({})
  12.     cookiejar = http.cookiejar.MozillaCookieJar(cookies_filename) # 加载cookies内容 cookiejar.save()能够保存文件
  13.     cookie_support = urllib.request.HTTPCookieProcessor(cookiejar)
  14.     opener = urllib.request.build_opener(proxy_support,cookie_support)# urllib钢铁侠组配
  15.     opener.addheaders =
  16.     urllib.request.install_opener(opener) #urllib钢铁侠开机初始化
  17.     return cookiejar

  18. def getjson(url):
  19.     response  = urllib.request.urlopen(url)
  20.     data_json = json.loads(response.read())
  21.     return data_json

  22. def getjson_post(url,data):
  23.     req       = urllib.request.Request(url)
  24.    
  25.     # Post的数据类型选择
  26.     # data_coded = urllib.parse.urlencode(data).encode('utf-8')
  27.     # req.add_header('Content-Type', 'application/x-www-form-urlencoded')
  28.    
  29.     # 提交Json要改变默认的Content-Type类型
  30.     data_coded = json.dumps(data).encode('utf-8')
  31.     req.add_header('Content-Type', 'application/json; charset=utf-8')
  32.     # 如果需要对单个请求进行进一步客制化 其中的urlopen()还需要生成request实例进行自定义。
  33.     response  = urllib.request.urlopen(req,data_coded)
  34.     data_json = json.loads(response.read())
  35.     return data_json

  36. def getjson_header(url,header_dict):
  37.     # header_list =
  38.     req  = urllib.request.Request(url)
  39.     for key in header_dict:
  40.         req.add_header(key, header_dict)
  41.     response  = urllib.request.urlopen(req)
  42.     data_json = json.loads(response.read())
  43.     return data_json

  44. # 初始化容器,使其能够保存Cookies,
  45. cookiejar = cake_init(proxy=proxy)
  46. # cookiejar.save()

  47. ip_api_url = 'http://ip-api.com/json/?fields=61439'

  48. data = {'a':1,'b':2}
  49. # 对跨站检测有用,防止视频链接被其他网站直接调用,会检测视频来源
  50. header_dict = {'Referer':'https://www.douyin.com/'}

  51. s_get_dict = getjson(ip_api_url)
  52. s_get_dict = getjson_post(ip_api_url,data)
  53. s_get_dict = getjson_header(ip_api_url,header_dict)

  54. response = requests.get(ip_api_url,proxies={'https':proxy})
  55. response = requests.post(ip_api_url,json=data,proxies={'https':proxy})
  56. res_json = response.json()

  57. print('----------------------IP Information Begin--------------------------')
  58. for key in s_get_dict:
  59.     print('%s : %s' % (key, s_get_dict))
  60. print('----------------------IP Information End--------------------------\n')


  61. print('----------------------IP Information Begin--------------------------')
  62. for key in res_json:
  63.     print('%s : %s' % (key, res_json))
  64. print('----------------------IP Information End--------------------------\n')
复制代码


希望这可以帮助到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 05:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表