《Python 网络爬虫简易速速上手小册》第3章:Python 网络爬虫的设计(2024 最新版)

在这里插入图片描述

文章目录

  • 3.1 设计高效的爬取策略
    • 3.1.1 重点基础知识讲解
    • 3.1.2 重点案例:使用 Scrapy 框架进行并发爬取
    • 3.1.3 拓展案例 1:使用 Requests 和 gevent 进行异步请求
    • 3.1.4 拓展案例 2:利用缓存机制避免重复请求
  • 3.2 管理爬虫的请求频率
    • 3.2.1 重点基础知识讲解
    • 3.2.2 重点案例:使用 time.sleep 控制请求频率
    • 3.2.3 拓展案例 1:遵守 robots.txt
    • 3.2.4 拓展案例 2:利用 Scrapy 的 DOWNLOAD_DELAY 设置
  • 3.3 应对网站的反爬虫措施
    • 3.3.1 重点基础知识讲解
    • 3.3.2 重点案例:使用代理 IP 和伪装 User-Agent
    • 3.3.3 拓展案例 1:处理 Cookies
    • 3.3.4 拓展案例 2:验证码自动识别

3.1 设计高效的爬取策略

在网络爬虫的世界里,效率是王道。一个高效的爬虫可以在最短的时间内抓取最多的数据,同时减少对目标网站的负担。下面,我们将探讨如何设计出这样的爬虫。

3.1.1 重点基础知识讲解

  • 并发请求:通过同时发送多个请求,你可以显著提高爬虫的数据收集速度。但请注意,过多的并发请求可能会给网站服务器带来压力,甚至导致你的 IP 被封禁。
  • 缓存策略:避免重复请求同一页面。通过实现缓存机制,保存已经访问过的页面,可以减少不必要的网络请求,提高爬虫效率。
  • 请求头管理:合理设置 User-Agent 和 Referer 等 HTTP 头部信息,可以帮助你的爬虫更好地模拟正常用户的行为,避免被网站的反爬虫策略识别。
  • 数据抽取效率:使用高效的数据抽取方法(如 CSS 选择器、XPath),可以快速从 HTML 文档中提取出需要的数据。

3.1.2 重点案例:使用 Scrapy 框架进行并发爬取

假设我们要收集一个在线论坛(如 Reddit)上的帖子信息。Scrapy 是一个高效的爬虫框架,支持并发请求,非常适合这种任务。

import scrapyclass RedditSpider(scrapy.Spider):name = 'reddit_spider'start_urls = ['https://www.reddit.com/r/Python/']def parse(self, response):for post in response.css('div.Post'):yield {'title': post.css('h3::text').get(),'url': post.css('a::attr(href)').get()}

3.1.3 拓展案例 1:使用 Requests 和 gevent 进行异步请求

如果你需要一个轻量级的解决方案,可以使用 Requests 库配合 gevent 进行异步请求。这适用于简单的爬虫任务,需要快速实施而不引入 Scrapy 这样的大型框架。

import gevent
from gevent import monkey; monkey.patch_all()
import requestsdef fetch_url(url):print(f"Fetching {url}")response = requests.get(url)print(f"{url}: {len(response.content)} bytes.")urls = ['https://www.example.com/page1', 'https://www.example.com/page2']jobs = [gevent.spawn(fetch_url, url) for url in urls]
gevent.wait(jobs)

3.1.4 拓展案例 2:利用缓存机制避免重复请求

对于复杂的爬虫项目,使用一个本地或远程缓存来存储已经访问过的页面的数据,可以避免重复爬取相同的内容。下面是一个简单的示例,使用 Python 的 shelve 模块作为缓存机制。

import shelve
import requestscache = shelve.open("cache.db")def get_page(url):if url in cache:return cache[url]else:response = requests.get(url)cache[url] = response.textreturn response.textcontent = get_page('https://www.example.com')
print(content)cache.close()

通过这些案例,我们看到了设计高效爬虫策略的不同方面,从并发请求到缓存策略,再到请求头管理和数据抽取效率。应用这些策略,可以让你的爬虫项目既高效又友好,保证了数据收集的速度同时,也尊重了目标网站的服务器资源。

在这里插入图片描述


3.2 管理爬虫的请求频率

控制爬虫的请求频率是确保你的爬虫不会给目标网站带来过大负担的关键。正确管理请求频率不仅可以避免你的 IP 被封锁,还是对网站资源的一种尊重。

3.2.1 重点基础知识讲解

  • 限制请求速率:通过设置爬虫在连续两次请求之间的等待时间,来控制爬虫的请求速率。这可以通过编程中的 sleep 函数轻松实现。
  • 自动化遵守 robots.txt:许多网站通过 robots.txt 文件声明了哪些内容可以被爬虫抓取。尊重这一声明是良好的网络公民的表现。
  • 动态调整请求间隔:基于网站的反馈动态调整请求频率。例如,如果遇到 429 Too Many Requests 错误,可以增加等待时间。
  • 使用爬虫中间件:在一些高级的爬虫框架中,如 Scrapy,可以利用或自定义中间件来管理请求频率。

3.2.2 重点案例:使用 time.sleep 控制请求频率

假设你需要从一个博客网站上抓取最新文章的标题。为了避免因请求频率过高而被封 IP,你可以在每次请求之间添加延时。

import time
import requests
from bs4 import BeautifulSoupurls = ['https://blog.example.com/page1', 'https://blog.example.com/page2']for url in urls:response = requests.get(url)soup = BeautifulSoup(response.text, 'html.parser')for article in soup.find_all('article'):title = article.find('h2').textprint(f"文章标题: {title}")time.sleep(1)  # 每次请求之间暂停 1 秒

3.2.3 拓展案例 1:遵守 robots.txt

在你的爬虫项目中遵守目标网站的 robots.txt 是一个好习惯。以下示例使用 robotparser 来检查爬虫是否被允许访问特定的 URL。

import urllib.robotparserrp = urllib.robotparser.RobotFileParser()
rp.set_url("https://www.example.com/robots.txt")
rp.read()url = "https://www.example.com/somepage"
user_agent = 'MySpider/1.0'if rp.can_fetch(user_agent, url):print("可以爬取")
else:print("不允许爬取")

3.2.4 拓展案例 2:利用 Scrapy 的 DOWNLOAD_DELAY 设置

如果你使用 Scrapy 框架,可以通过在 settings.py 文件中设置 DOWNLOAD_DELAY 来控制请求频率。这是一个简单有效的方法,让 Scrapy 自动为你管理请求间隔。

# Scrapy settings.py
BOT_NAME = 'my_spider'DOWNLOAD_DELAY = 2  # 在每次请求之间设置 2 秒的延迟

通过以上案例,我们了解到管理爬虫的请求频率不仅对于避免被网站封锁至关重要,也体现了我们对网站资源的尊重。无论是简单的使用 time.sleep,遵守 robots.txt 的规则,还是利用高级框架如 Scrapy 的内置功能,合理控制爬虫的请求频率都是设计高效且负责任爬虫的重要一环。

在这里插入图片描述


3.3 应对网站的反爬虫措施

随着网络爬虫技术的普及,越来越多的网站开始采用各种反爬虫措施来保护自己的数据。作为一名负责任的爬虫开发者,了解这些措施并采取适当的应对策略是非常重要的。

3.3.1 重点基础知识讲解

  • 用户代理(User-Agent)伪装:一些网站会检查 HTTP 请求的 User-Agent 字段,来判断访问者是否为爬虫。通过修改 User-Agent,可以让爬虫伪装成浏览器访问。
  • 处理 Cookies:某些网站要求客户端支持 Cookies 来跟踪会话。正确处理 Cookies 可以提高爬虫的成功率。
  • 动态 IP 和代理:频繁的请求可能导致 IP 地址被封锁。使用动态 IP 或代理服务可以避免这一问题。
  • 验证码识别:对于需要输入验证码的网站,可以使用 OCR(光学字符识别)技术或第三方服务来自动识别验证码。

3.3.2 重点案例:使用代理 IP 和伪装 User-Agent

假设你需要从一个有反爬虫措施的网站上抓取信息。为了避免被封锁,你决定使用代理 IP 和伪装 User-Agent。

import requests
from fake_useragent import UserAgent# 生成伪装的 User-Agent
ua = UserAgent()
headers = {'User-Agent': ua.random}# 设置代理 IP
proxies = {'http': 'http://10.10.1.10:3128','https': 'http://10.10.1.10:1080',
}url = "https://www.example.com/data"response = requests.get(url, headers=headers, proxies=proxies)
print(response.text)

3.3.3 拓展案例 1:处理 Cookies

有些网站需要维护会话 Cookies。以下示例展示了如何使用 Requests 库在会话中保持 Cookies。

import requestssession = requests.Session()  # 创建一个会话实例# 首次访问获取 Cookies
response = session.get('https://www.example.com/login')
# 后续请求会自动处理 Cookies
response = session.get('https://www.example.com/dashboard')print(response.text)

3.3.4 拓展案例 2:验证码自动识别

对于简单的验证码,可以使用 OCR 技术尝试自动识别。这里使用 pytesseract 来识别验证码图片。

import pytesseract
from PIL import Image
import requests
from io import BytesIO# 获取验证码图片
response = requests.get('https://www.example.com/captcha.png')
img = Image.open(BytesIO(response.content))# 使用 pytesseract 识别验证码
captcha_text = pytesseract.image_to_string(img)
print(f"识别的验证码是: {captcha_text}")# 使用识别出的验证码继续访问网站
# response = requests.post('https://www.example.com/login', data={'captcha': captcha_text})
# ...

通过以上案例,我们了解到如何应对网站的常见反爬虫措施。虽然有许多技术可以帮助我们绕过这些限制,但重要的是要确保我们的爬虫活动遵守法律法规,尊重网站的数据使用协议。合理合法地使用爬虫技术,既可以获得我们需要的数据,也可以保护网站的合法权益。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/453444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React 中实现拖拽功能-插件 react-beautiful-dnd

拖拽功能在平时开发中是很常见的,这篇文章主要使用react-beautiful-dnd插件实现此功能。 非常好用,附上GitHub地址:https://github.com/atlassian/react-beautiful-dnd 安装及引入 // 1.引入 # yarn yarn add react-beautiful-dnd# npm npm…

uniapp android和微信小程序实现PDF在线预览

在使用uniapp开发移动端时,微信开发者工具里webview能正常打开后端接口返回的pdf文件流。正式发布后,在配置了业务域名和服务器域名的前提下,预览pdf文件却只能看到白屏,因此我猜测微信小程序不能通过webview读取文件流。这个想法…

【分布式】雪花算法学习笔记

雪花算法学习笔记 来源 https://pdai.tech/md/algorithm/alg-domain-id-snowflake.html概述 雪花算法是推特开源的分布式ID生成算法,以划分命名空间的方式将64位分割成多个部分,每一个部分代表不同的含义,这种就是将64位划分成不同的段&…

支持向量机

支持向量机(Support Vector Machine,SVM)是一个非常优雅的算法,具有非常完善的数学理论,常用于数据分类,也可以用于数据的回归预测中。支持向量机在许多领域都有广泛的应用,如文本分类、图像识别…

Alt + TAB 禁止在 Edge 标签页之间切换

(原文:https://blog.iyatt.com/?p13587 ) 浏览器标签页之间切换可以用 {Ctrl}{Tab} 或者 {Ctrl}{数字}精准到标签页码,结果 Windows 11 默认把 Edge 标签页切换混入了 {Alt}{Tab} 前台应用窗口切换,经常不注意是在 Ed…

LeetCode:2.两数相加

目录 题目:​编辑2. 两数相加 - 力扣(LeetCode) 分析问题: 官方的优秀代码博主的注释: 博主的辣眼代码,无注释,拉出来拷打自己: 每日表情包: 2. 两数相加 - 力扣&am…

SpringBoot异步任务

一、注解实现 EnableAsync注解 创建一个配置类,并在类上添加EnableAsync注解,用来启用异步支持。 Configuration EnableAsync public class AsyncConfig { }或者,在启动类上添加EnableAsync注解,用来启用异步支持。 EnableAsy…

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁👊 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 💝 问题背景 今天寸铁在…

最新GPT4.0使用教程,AI绘画,GPT语音对话使用,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画,文档对话总结DALL-E3文生图,相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚至也可以和…

大模型日报-20240204

文章目录 大模型也有小偷?为保护你的参数,上交大给大模型制作「人类可读指纹」阿里全新Agent玩转手机:刷短视频自主点赞评论,还学会了跨应用操作代谢数据集上四项指标达94%~98%,西南交大团队开发多尺度图神经网络框架&…

2024杭州国际安防展览会:引领数字城市安全与智能未来

随着科技的不断进步,数字城市已经成为未来城市发展的重要趋势。作为数字城市建设的重要组成部分,安防技术的创新与应用对于保障城市安全、提高生活品质具有重要意义。为此,2024杭州国际安防展览会将于4月份在杭州国际博览中心隆重召开&#x…

物联网与智慧景区的未来:机遇与挑战并存

随着科技的不断发展,物联网技术在智慧景区中的应用越来越广泛,为旅游业带来了巨大的变革。然而,在物联网与智慧景区的未来发展中,机遇与挑战并存。本文将探讨物联网与智慧景区面临的机遇和挑战,并提出应对措施&#xf…