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

news2024/11/28 18:47:21

在这里插入图片描述

文章目录

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AIGC核心技术剖析】AI生成音乐:MAGNeT一种直接操作多个音频令牌流的掩码生成序列建模方法

MAGNeT是一种直接操作多个音频令牌流的掩码生成序列建模方法。与先前的工作不同,MAGNeT由一个单阶段、非自回归的变压器组成。在训练期间,论文使用掩码调度器预测从掩码令牌中获得的跨度,而在推断期间,论文通过多个解码步骤逐渐构…

微信小程序 使用npm包

1. 微信小程序 使用npm包 1.1. npm初始化 如果你的小程序项目没有安装过npm包的话,你需要先初始化npm npm init1.2. 安装npm包 这里以vant-weapp(小程序UI组件库)为例: npm i vant-weapp -S --production1.3. npm包构建 1.3.1. 点击微信开发者工具右…

怎样理解Vue单向数据流

在前端开发中,数据流是一个非常重要的概念。Vue.js作为一种流行的前端框架,采用了单向数据流的架构,旨在简化开发过程并提高应用的可维护性。本文将探讨Vue单向数据流的含义以及它的使用方法。 什么是单向数据流? 在Vue中&#…

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

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

动态颗粒背景,适合VUE、HTML前端显示

动态颗粒背景&#xff0c;适合做背景使用&#xff0c;VUE、HTML前端显示直接看效果 废话不多说直接上代码&#xff1b; 一、html 代码部分 <template><div id"login"><div class"container"><div class"login-form"&g…

golang开发window环境搭建

1.本人开发环境&#xff1a;window10,idea2020.1.3 2.Go语言环境版本1.5.1 2.1. go语言插件 下载地址 csdn - 安全中心 2.2下载安装 3.idea配置go环境 4.创建go项目 、5.运行

第二届 N1CTF Junior WEB方向 部分题解WP

zako 题目描述&#xff1a;很简单的rce哦 启动环境&#xff0c;源码直接给了。 execute.sh #!/bin/bashreject(){echo ${1}exit 1 }XXXCMD$1awk -v str"${XXXCMD}" \ BEGIN{deny";&$(){}[]!#$%^&*-";for(i 1; i < length(str); i){char su…

Unity引擎学习笔记之【混合动画操作】

混合动画Hybrid Animation Unity中的Blend Tree是一种动画混合技术&#xff0c;它允许开发者通过添加多个动画片段&#xff08;例如奔跑、行走、跳跃等&#xff09;来创建复杂的角色动画。Blend Tree允许在不同的状态下平滑地过渡并混合不同的动画。例如&#xff0c;在奔跑和行…

PyTorch 2.2 中文官方教程(九)

在生产环境中部署 PyTorch 模型 通过 Flask 在 Python 中部署 PyTorch 的 REST API 原文&#xff1a;pytorch.org/tutorials/intermediate/flask_rest_api_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 注意 点击这里下载完整的示例代码 作者&#…

1997-2022年中央对各省份一般公共预算转移支付数据

1997-2022年中央对各省份一般公共预算转移支付数据 1、时间&#xff1a;1997-2022年 2、范围&#xff1a;31省 3、指标&#xff1a;一般公共预算转移支付 4、来源&#xff1a;wind 财政部 5、指标解释&#xff1a;一般性转移支付又称体制性转移支付&#xff0c;是指上级政…

机器学习本科课程 实验3 决策树处理分类任务

实验3.1 决策树处理分类任务 使用sklearn.tree.DecisionTreeClassifier完成肿瘤分类&#xff08;breast-cancer&#xff09;计算最大深度为10时&#xff0c;十折交叉验证的精度(accuracy)&#xff0c;查准率(precision)&#xff0c;查全率(recall)&#xff0c;F1值绘制最大深度…

前端学习第4天

一、复合选择器 1.后代选择器 2.子代选择器 3.并集选择器 4.交集选择器 5.伪类选择器 1.伪类-超链接&#xff08;拓展&#xff09; 二、CSS特性 1.继承性 body放在style中 2.层叠性 3.优先级 属性 !important;&#xff08;最高优先级&#xff09; 1.优先级-叠加计算规则 2.em…

枚举(Java)

一、概念 枚举是一种特殊的类。 格式&#xff1a; 修饰符 enum 枚举类名{ 对象名称1&#xff0c;对象名称2&#xff0c;....; 其他成员... } 二、枚举类的特点 1.枚举类的第一行只能罗列一些名称&#xff0c;并且这些名称都是常量&#xff0c;每个常量记住一个枚举类对象…

Quartus IP 之mif与hex文件创建与使用

一、mif与hex概述 ROM IP的数据需要满足断电不丢失的要求&#xff0c;ROM IP数据的文件格式一般有三种文件格式&#xff1a;.mif、.hex、.coe&#xff0c;Xilinx与Intel Altera支持的ROM IP数据文件格式如下&#xff1a; Xilinx与Altera支持的ROM文件格式 Alterahex、mifAM&am…

基于微信小程序的书籍阅读系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

ACPF UI 框架设计与基础实现

世态人情,比明月清风更饶有滋味;可作书读,可当戏看。书上的描摹,戏里的扮演,即使栩栩如生,究竟只是文艺作品;人情世态,都是天真自然的流露,往往超出情理之外,新奇得令人震惊,令人骇怪,给人以更深刻的效益,更奇妙的娱乐。惟有身处卑微的人,最有机缘看到世态人情的…

【python】python爱心代码【附源码】

一、实现效果&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 二、完整代码&#xff1a; import math import random import threading import time from math import sin, cos, pi, log from tkinter import * import re# 烟花相关设置 Fireworks [] m…

离线下载安装postgresql12/13/14/15.

前言 参考此链接&#xff0c;但是有问题 1.下载离线rpm包 下载安装postgresql-devel 12以上版本&#xff0c;去postgresql下载官网&#xff0c;然后自己选择是pg12还是13、14、15等。&#xff08;我选的12&#xff09;。不想麻烦的直接去我这资源直接下载 下载这个五个文件&…

CHS_09.2.3.6_2+多生产者-多消费者

CHS_09.2.3.6_2多生产者-多消费者 问题描述问题分析如何实现如何实现假如我们把盘子的容量设为二知识回顾 在这个小节中 我们会学习一个多生产者 多消费者的这样一个问题模型 问题描述 先来看一下问题的描述 假设桌子上面有一个盘子 每次只能向这个盘子里放一个水果 有四个人…

SpringBoot 各种回滚骚操作实战

事务定义 事务&#xff0c;就是一组操作数据库的动作集合。事务是现代数据库理论中的核心概念之一。如果一组处理步骤或者全部发生或者一步也不执行&#xff0c;我们称该组处理步骤为一个事务。当所有的步骤像一个操作一样被完整地执行&#xff0c;我们称该事务被提交。由于其…