Redian新闻
>
爬虫必备requests的扩展包总结

爬虫必备requests的扩展包总结

科技

这篇文章是伟兄给我的稿子,总结实用、到位。另外,欢迎访问并关注他的博客:

https://jl-zhenlaixiaowei.blog.csdn.net/


Requests-Cache的安装与测试

Requests-Cache模块是requests模块的一个扩展功能,用于为requests模块提供持久化缓存支持。如果requests模块向一个URL发送重复请求时,Requests-Cache模块将会自动判断当前的网络请求是否产生了缓存。如果已经产生了缓存,就会从缓存中读取数据作为响应内容。如果没有缓存就会向服务器发送网络请求,获取服务器所返回的响应内容。使用Requests-Cache模块可以减少网络资源避免重复请求的次数,这样可以变相地躲避一些反爬机制。

说 明

无论是否使用了Anaconda,都需要单独安装Requests-Cache模块,因为Anaconda中并不包含该模块。

Python 3.9.9 (v3.9.9:ccb0e6a345, Nov 15 202113:29:20
[Clang 6.0 (clang-600.0.57)] on darwin
>>>import requests_cache
>>>version = requests_cache.__version__
>>>print(version)
0.9.1

缓存的应用

调用install_cache()函数实现Requests-Cache的请求,语法格式如下:

install_cache(cache_name='cache', backend=None, expire_after=None, allowable_codes=(200, ), allowable_methods=('GET', ), session_factory=<class 'requests_cache.core.CachedSession'>,
**backend_options)

Install_cache()函数中包含了多个参数,每个参数的含义如下:

§ cache_name: 表示缓存文件的名称,默认为cache

§ backend: 表示设置缓存的存储机制,默认为None,表示默认使用sqlite进行存储

§ expire_after: 表示设置缓存的有效时间,默认为None,表示永久有效

§ allowable_codes:表示设置状态码,默认为200

§ allowable_methods:表示设置请求方式,默认为GET,表示只有GET请求才可以生产缓存

§ session_factory:  表示设置缓存执行的对象,需要实现CachedSession类

§ **backend_options: 如果缓存的存储方式为sqlite、mongo、redis数据库,该参数表示设置数据库的连接方式

在使用install_cache()函数实现请求缓存时,一般情况下时不需要单独设置任何参数的,只需要使用默认参数即可。判断是否存在缓存的代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :1/30/22 8:32 AM
# 文件      :判断缓存是否存在.py
# IDE      :PyCharm

# 导入requests_cache模块
import requests_cache

# 导入网络请求模块
import requests

# 设置缓存
requests_cache.install_cache()

# 清理缓存
requests_cache.clear()

# 定义测试地址
url = 'http://httpbin.org/get'

# 第一次发送网络请求
r = requests.get(url)

# False表示不存在缓存
print('是否存在缓存:', r.from_cache)

# 第二次发送网络请求
r = requests.get(url)

# True表示存在缓存
print('是否存在缓存:', r.from_cache)

程序运行结果如下:

是否存在缓存: False
是否存在缓存: True

针对反爬措施,在多次请求中设置延时是不错的选择。但是如果在第一次请求后生成了缓存,那么第二次请求时就无需设置延时,为此Requests-Cache模块可以使用自定义钩子函数的方式,合理判断是否需要设置延时操作。示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :1/30/22 8:57 AM
# 文件      :利用钩子函数判断是否需要设置延时.py
# IDE      :PyCharm

# 导入Requests_Cache模块
import requests_cache

# 导入时间模块
import time

# 设置缓存
requests_cache.install_cache()

# 清理缓存
requests_cache.clear()

# 定义钩子函数
def make_throttle_hook(timeout = 0.1):
    def hook(response, *args, **kwargs):
        print(response.text)
        # 判断没有缓存时就添加延时
        if not getattr(response, 'from_cache'False):
            print('等待', timeout, '秒!')
            # 等待指定时间
            time.sleep(timeout)
        else:
            # 存在缓存输出True
            print('是否存在请求缓存!', response.from_cache)
        return response
    return hook

if __name__ == '__main__':
    requests_cache.install_cache()
    requests_cache.clear()
    s = requests_cache.CachedSession()
    s.hooks = {'response': make_throttle_hook(2)}   # 配置钩子函数

    # 模拟发送第一次网络请求
    s.get('http://httpbin.org/get')
    # 模拟发送第二次网络请求
    s.get('http://httpbin.org/get')

程序运行结果:

第一次运行结果:

{
  "args": {}, 
  "headers": {
    "Accept""*/*"
    "Accept-Encoding""gzip, deflate"
    "Host""httpbin.org"
    "User-Agent""python-requests/2.27.1"
    "X-Amzn-Trace-Id""Root=1-61f5e91a-5c923abe41da544561b5f400"
  }, 
  "origin""139.209.219.102"
  "url""http://httpbin.org/get"
}

等待2秒

第二次请求结果

{
  "args": {}, 
  "headers": {
    "Accept""*/*"
    "Accept-Encoding""gzip, deflate"
    "Host""httpbin.org"
    "User-Agent""python-requests/2.27.1"
    "X-Amzn-Trace-Id""Root=1-61f5e91a-5c923abe41da544561b5f400"
  }, 
  "origin""139.209.219.102"
  "url""http://httpbin.org/get"
}

二次请求存在缓存

是否存在请求缓存! True

从以上的运行结果看,通过配置钩子函数可以实现:在第一次请求时,因为没有请求缓存所以执行了2秒等待延时;第二次请求时则没有执行2秒 延时,并输出是否存在请求缓存行为True。

说 明

Requests-Cache模块支持4种不同的存储机制,分别为money、sqlite、mongoDB以及redid,具体说明如下:

§ memory: 以字典的形式将缓存存储在内存当中,程序运行完后缓存将被销毁

§ sqlite: 将缓存存储在sqlite数据库中

§ mongoDB:将缓存存储在mongoDB数据库中

§ redis: 将缓存存储在redis数据库当中

使用Requests-Cache模块指定缓存不同的存储机制时,只需要为install_cache()函数中backend参数赋值即可,设置方式如下:

# 导入Requests_Cache模块
import requests_cache

# 设置缓存为内存的存储机制
requests_cache.install_cache(backend='memory')

# 设置缓存为sqlite数据库的存储机制
requests_cache.install_cache(backend='sqlite')

# 设置缓存为mongoDB数据库的存储机制
requests_cache.install_cache(backend='mongoDB')

# 设置缓存为redis数据库的存储机制
requests_cache.install_cache(backend='redis')

设置存储机制为mongoDB与redis数据库时,需要提取安装对应的操作模块与数据库。安装模块的命令如下:

pip install pymongo
pip install redis

强大的Requests-HTML模块

Requests-HTML 模块是requets模块的亲兄弟,是同一个开发者所开发的。Requests-HTML模块不仅包含了requests模块中的所有功能,还增加了对JavaScript的支持、数据提取以及模拟真实浏览器等功能。

使用Requests-HTML模块实现网络请求

§ 1、get()请求

通过'pip install requests-html'命令进行模块的安装,然后导入Requests-HTML模块中的HTMLSession类,接着需要创建HTML会话对象,通过会话实例进行网络请求的发送,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :1/30/22 3:48 PM
# 文件      :使用Requests-HTML模块实现网络请求.py
# IDE      :PyCharm

# 导入HTMLSession类
from requests_html import HTMLSession

# 创建HTML会话对象
session = HTMLSession()

# 定义请求地址
url = 'http://news.youth.cn/'

# 发送网络请求
r = session.get(url)

# 打印网络请求的URL地址
print(r.html)

程序运行结果如下:

<HTML url='http://news.youth.cn/'>

§ 2、post()请求

在实现网络请求时,POST请求也是一种比较常见的请求方式,使用Requests-HTML实现POST请求与requests的实现方法类似都需要单独设置表单参数data,不过它也是需要通过会话实例进行网络请求的发送,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :1/30/22 4:44 PM
# 文件      :post()请求.py
# IDE      :PyCharm

# 导入HTMLSession类
from requests_html import HTMLSession

# 创建HTML会话对象
session = HTMLSession()

# 模拟表单登录的数据
data = {'user':'admin''password':123456}

# 发送POST请求
r = session.post('http://httpbin.org/post', data = data)
# 判断请求是否成功
if r.status_code == 200:
    print(r.text)

程序运行结果如下:

{
  "args": {}, 
  "data"""
  "files": {}, 
  # 表单数据
  "form": {
    "password""123456"
    "user""admin"
  }, 
  "headers": {
    "Accept""*/*"
    "Accept-Encoding""gzip, deflate"
    "Content-Length""26"
    "Content-Type""application/x-www-form-urlencoded"
    "Host""httpbin.org"
    # User-Agent对应的值
    "User-Agent""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"
    "X-Amzn-Trace-Id""Root=1-61f6509d-56a381b4543229480fe07e56"
  }, 
  "json": null, 
  "origin""139.209.219.102"
  "url""http://httpbin.org/post"
}

从以上的运行结果中,不仅可以看到form所对应的表单内容,还可以看到User-Agent所对应的值,并不是像requests模块发送网络请求时返回的默认值(python-requests/2.27.1),而是一个真实的浏览器请求头信息,这与requests模块所发送的网络请求有着细小的改进。

§ 3、修改请求头信息

说到请求头信息,Requests-HTML模块是可通过指定headers参数来对默认的浏览器请求头信息进行修改的,修改请求头信息的关键代码如下:

ua = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.76'
}
r = session.post('http://httpbin.org/post', data = data, headers = ua)

§ Requests-HTML模块中添加了UserAgent类,使用该类可以实现随机生成请求头。示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :1/30/22 9:06 PM
# 文件      :生成随机请求头信息.py
# IDE      :PyCharm

# 导入HTMLSession类
from requests_html import HTMLSession, UserAgent

# 创建HTML会话对象
session = HTMLSession()

# 创建随机请求头
ua =UserAgent().random
r = session.get('http://httpbin.org/get', headers = {'user-agent': ua})

# 判断请求是否成功
if r.status_code == 200:
    # 以文本形式打印返回结果
    print(r.text)

程序运行结果如下:

{
  "args": {}, 
  "headers": {
    "Accept""*/*"
    "Accept-Encoding""gzip, deflate"
    "Host""httpbin.org"
    # 请求头信息
    "User-Agent""Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0.6"
    "X-Amzn-Trace-Id""Root=1-61f69454-0b37eb40198f0f4b237fc7e8"
  }, 
  "origin""139.209.219.102"
  "url""http://httpbin.org/get"
}
{
  "args": {}, 
  "headers": {
    "Accept""*/*"
    "Accept-Encoding""gzip, deflate"
    "Host""httpbin.org"
    # 请求头信息
    "User-Agent""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1309.0 Safari/537.17"
    "X-Amzn-Trace-Id""Root=1-61f693aa-0d20428a3a73766723017536"
  }, 
  "origin""139.209.219.102"
  "url""http://httpbin.org/get"
}

备注

以上运行是在Anaconda的Jupiter notebook 下运行。Pycharm 报错,应该是解释器的问题。

数据的提取

以往使用requests模块实现爬虫程序时,还需要为其配置一个解析HTML代码的搭档。Requests-HTML模块对此进行了一个比较大的升级,不仅支持CSS选择器还支持XPath的节点提取方式。

1、CSS选择器

CSS选择器中需要使用HTML的find()方法,该方法中包含5个参数,其语法格式与参数含义如下:

find(selector:str='*', containing:_Containing=None, clean:bool=False,first:bool=False,_encoding:str=None)

§ selector: 使用CSS选择器定位网页元素

§ containing:通过指定文本获取网页元素

§ clean:是否清除HTML中的

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
National Treasure: Under a Village, China Hunts for Lost HistoryChinese Courts See Rise in Emojis Used as Evidence in LawsuitsWith Bittersweet Memories, Students Leave Shanghai in Droves爬虫必备Beautiful Soup包使用详解Chinese Cities Loosen Housing Policies for Three-Child Families圣帕特里克节染绿芝加哥河 绝美!Abrupt Closure of Non-Academic Training Centers Raises Questions使用 Python 的 requests 和 Beautiful Soup 来分析网页 | Linux 中国其实五十来年前, 应该叫陈永贵当外交部长, 陈阿大做国防部长,顾阿桃做教育部长Wheat Destroyed Before Harvest Prompts Food Crisis DiscussionNew Rules for Schools in Shanghai, Added Pressure for StudentsChina to Review School Textbooks After Questionable IllustrationNew Sanxingdui Relics Offer More Clues of Ancient CivilizationWhat Shanghai’s Locked-Down Residents are Trying to Buy西雅图周末不无聊|夏天的紫色浪漫! 快来Sequim Lavender Festival看薰衣草啦!爬虫玩得好,牢饭吃到饱?这3条底线千万不能碰!体验完可以插 SIM 卡的扩展坞后,我感觉当了回冤大头。。。Chinese Provinces Seek Fertility Treatments to Boost Birth RateIs Studying Overseas Losing Its Allure for Chinese Students?Falling Grades, Threats, Toxic Culture: Why a Fan Quit Her Idol[单车] 一台有缘的手工钢架——Equilibrium E1Cities Raise Testing Frequency to Catch COVID Cases Early西雅图周末不无聊|一整个夏天都有免费音乐会听啦!就在Bellevue Beats Summer Concerts!ERL x Dior ,「加速」了 Guest Designer 这种高级时装联名形式?常用的盘盘碟碟 - Farmhouse Touch (多图)Shenzhen Funeral Home Requires COVID Test Result for DeadVR游戏周报 | Steam、Quest夏日特卖,《半衰期 爱莉克斯》五折优惠精选Data岗位 | American Equity、NYSCF等公司最新职位发布!爬虫案例:拉勾网工作职位爬取A Shanghai District Declares Snap Lockdown for COVID Testing追梦的女孩男孩:看电影【健听女孩】和【倒数时刻】Residents Crowd COVID Test Sites to Move Across Shanghai Freely从Redis7.0发布看Redis的过去与未来快刀牙医China Restricts Citizens From ‘Non-Essential’ Foreign Travel
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。