《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 scrapy

class 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 requests

def 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 requests

cache = shelve.open("cache.db")

def get_page(url):
    if url in cache:
        return cache[url]
    else:
        response = requests.get(url)
        cache[url] = response.text
        return response.text

content = 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 BeautifulSoup

urls = ['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').text
        print(f"文章标题: {title}")
    
    time.sleep(1)  # 每次请求之间暂停 1 秒

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

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

import urllib.robotparser

rp = 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 requests

session = 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})
# ...

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

08. 【Linux教程】CentOS 目录介绍

CentOS 目录介绍 前面小节介绍了如何安装并登录连接 CentOS 系统,本小节围绕 CentOS 系统的目录,介绍其各个目录的作用,方便读者以后在工作中很好地将项目和软件归类存储,熟悉 CentOS 系统各个目录的功能介绍,有助于加…

【GAMES101】Lecture 15 全局光照

本节继承上一节的难度并继续加深,讲这个BRDF,然后理解反射方程和渲染方程,最终实现全局光照,以下内容很抽象……如果想要深入理解建议到隔壁基于物理着色:BRDF - 知乎 (zhihu.com)或者多看几遍视频,我也是回…

【51单片机】74HC595芯片实现单片机 IO 扩展(串转并)和 LED点阵实验

目录 单片机 IO 扩展(串转并)74HC595 芯片介绍硬件设计软件实验实验现象 LED点阵实验LED 点阵介绍硬件设计软件设计LED点阵(点亮一个点)LED 点阵(显示数字)LED 点阵(显示图像) 橙色 …

发送get请求并且发送请求头(header),java实现

发送get请求时,发送请求头(Header)中的内容 方便第二次调用其他url时传递参数,例如userCode或者租户编码 调用方式 Autowired private HttpServletRequest request;先注入HttpServletRequestpublic xxx xxx(){String url &quo…

后端程序员入门react笔记(一)

相关参考 react 首先,我们先大概了解一下什么是react以及react可以干什么。 React 是 Facebook 开源的一个用于构建用户界面的一款 JavaScript 库,主要用于构建 UI。 react的特点 声明式编程 react使用jsx进行渲染,这是一种类似html的语法…

(5)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—12种聚类算法说明与归纳

目录 一、12种聚类(无监督学习)算法说明和区分比较 聚类算法的类型(一) ​编辑导入函数库 加载数据集 ​编辑 (1)K-Means --Centroid models (2)Mini-Batch K-Means -- Centroid models (3)AffinityPropagation (Hierarchical) -- Connectivity models (4)Mean Shift…

靶机实战bwapp亲测xxe漏洞攻击及自动化XXE注射工具分析利用

靶机实战bwapp亲测xxe漏洞攻击及自动化XXE注射工具分析利用。 1|0介绍 xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目录遍历等.首先存在漏洞的web服务一定是存在xml传输数据的,可以在http头的content-type中查…

前后端数据校验

前端校验内容 前端开发中的必要校验,可以保证用户输入的数据的准确性、合法性和安全性。同时,这些校验也有助于提供良好的用户体验和防止不必要的错误提交到后端。 1、必填字段校验: 对于必填的字段,需确保用户输入了有效的数据…

PyTorch 2.2 中文官方教程(二十)

移动设备 在 iOS 上进行图像分割 DeepLabV3 原文:pytorch.org/tutorials/beginner/deeplabv3_on_ios.html 译者:飞龙 协议:CC BY-NC-SA 4.0 作者:Jeff Tang 审阅者:Jeremiah Chung 介绍 语义图像分割是一种计算机视…

InnoDB 锁系统(小白入门)

1995年 ,MySQL 1.0发布,仅供内部使用! 开发多用户、数据库驱动的应用时,最大的一个难点是:一方面要最大程度地利用数据库的并发访问,另一方面还要确保每个用户能以一致性的方式读取和修改数据。 MVCC 并发…

zabbix配置监控脚本

zabbix配置监控脚本 1.修改agent配置文件 [rootchang ~]# vim /etc/zabbix/zabbix_agentd.conf 333行 原# UnsafeUserParameters0 修改成 UnsafeUserParameters12.创建脚本与脚本存放目录 [rootchang ~]# mkdir /etc/zabbix/zabbix_scripts [rootchang zabbix_scripts]# vi…

电路分析2

7 等效电路的思想,简化不是目的,这个电路说明一切!_哔哩哔哩_bilibili 高中知识,翻笔记 8 什么时候用Y型?看到有有相同数字的时候,就可以考虑用 9 10 输入电阻还有没学完的 ok 11

Django的web框架Django Rest_Framework精讲(四)

文章目录 1.DRF认证组件Authentication2.权限Permissions3.限流Throttling4.过滤Filtering5.排序6.分页Pagination7.异常处理 Exceptions8.自动生成接口文档 大家好,我是景天,今天我们继续DRF的最后一讲,Django的web框架Django Rest_Framewor…

SpringBoot异步任务

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

Linux(二)

远程登录 Linux大多应用于服务器,而服务器不可能像PC一样放在办公室,它们是放在IDC机房的,所以我平时登录linux系统都是通过远程登录的。 Linux系统中是通过ssh服务实现的远程登录功能。默认ssh服务开启了22端口,而且当我们安装…

docker elasticsearch8启动失败

docker elasticsearch8.12.0启动后提示这个,并且始终无法访问localhost:9200 received plaintext http traffic on an https channel, closing connection Netty4HttpChannel 解决方案:重新创建 elasticsearch容器,加上 -e xpack.security.…

scikit-learn 1.3.X 版本 bug - F1 分数计算错误

如果您正在使用 scikit-learn 1.3.X 版本,在使用 f1_score() 或 classification_report() 函数时,如果参数设置为 zero_division1.0 或 zero_divisionnp.nan,那么函数的输出结果可能会出错。错误的范围可能高达 100%,具体取决于数…

ArcGIS学习(三)数据可视化

ArcGIS学习(三)数据可视化 1.矢量数据可视化 需要提前说明的是,在ArcGIS中,所有的可视化选项设置都是在“图层属性”对话框里面的“符号系统”中实现的。 对于矢量数据的可视化,主要有四种可视化方式: 按“要素”可视化按“类别”可视化按“数量”可视化按“图表”可视…

Leetcode—38. 外观数列【中等】

2024每日刷题&#xff08;111&#xff09; Leetcode—38. 外观数列 实现代码 class Solution { public:string countAndSay(int n) {string ans "1";while(--n) {string next;for(int i 0; i < ans.size(); i) {int cnt 1;char c ans[i];while(i 1 < an…

PyTorch 2.2 中文官方教程(十七)

&#xff08;Beta&#xff09;使用缩放点积注意力&#xff08;SDPA&#xff09;实现高性能 Transformer 原文&#xff1a;pytorch.org/tutorials/intermediate/scaled_dot_product_attention_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 注意 点击这…