当前位置: 首页 > article >正文

Scrapy-应对反爬虫机制

我们在运行爬虫的时候,如果爬取的网页较多,经常会遇到反爬虫问题,不让开发者进行爬取。因为现在很多网站都有相应的反爬虫机制,避免爬虫的而已爬取。所以,当我们要进行爬取大量网页的时候,很可能收到对方服务器的限制,从而被禁止,显然这不是我们想要的结果。在Scrapy项目中,主要可以通过以下方法来避免被禁止:

禁止Cookie

在Scrapy项目中的settings文件,可以发现文件中有以下代码:

# COOKIES_ENABLED = False

这句代码的用途是用来禁用Cookie的,只需将注释取消即可。让那些通过用户Cookie信息对用户进行识别和分析的网站无法识别我们,即无法禁止我们爬取。

设置下载延时与自动限速

有的网站会通过我们队网页的访问频率进行分析,如果爬取频率过快,则判断为爬虫自动爬取行为,识别后对我们进行相应限制,比如禁止我们再爬取该服务器上的网页等。对于这一类网站,我们只需要控制一下爬行时间间隔即可。在Scrapy项目中,我们可以直接在settings.py文件进行相应的设置:

DOWNLOAD_DELAY = 3

这样,我们就实现了下载延时的功能,下载网页的时间间隔将为3秒。设置好了之后,就可以避免被这一类反爬虫机制的网站禁止。其实DOWNLOAD_DELAY = 3settings.py中是存在的,只不过被注释了,我们只需要将这一行的注释取消即可。但是存在一个问题,DOWNLOAD_DELAY设置完成之后,不能动态改变,导致访问延时都差不多,也容易被发现。不过我们可以设置RANDOMIZE_DOWNLOAD_DELAY字段,进行动态调整:

RANDOMIZE_DOWNLOAD_DELAY = True

如果启用,当从相同的网站获取数据时,Scrapy将会等待一个随机的值,延迟时间为0.5到1.5之间的一个随机值乘以DOWNLOAD_DELAY。这回大大降低被发现的几率,有一些网站会检测访问延迟的相似性,也有被发现的可能。Scrapy提供了一种更智能的方法来解决限速的问题:通过自动限速扩展,该扩展能根据Scrapy服务器及爬取的网站的负载自动限制爬取速度。

Scrapy是如何实现自动限速扩展的呢?在Scrapy中,下载延迟是通过计算建立TCP连接并接收到HTTP包头之间的时间间隔来测量的,该扩展就是以此为前提进行编写的,实现自动限速功能组要几个重要的配置:

# 启动自动限速扩展
AUTOTHROTTLE_ENABLED = True

# 初始下载延时,单位为秒
AUTOTHROTTLE_START_DELAY = 5

# 在高延迟情况下的最大下载延迟,单位为秒
AUTOTHROTTLE_MAX_DELAY = 60

# 启动DEBUG模式
AUTOTHROTTLE_DEBUG = True

# 对单个网址进行并发请求的最大值
CONCURRENT_REQUESTS_PER_DOMAIN = 8

# 对单个IP进行并发请求的最大值,如果非零,则自动忽略CONCURRENT_REQUESTS_PER_DOMAIN
CONCURRENT_REQUESTS_PER_IP = 0

设置IP池

有的网站会对用户的IP进行检测,如果同一个IP在短时间内对自己服务器上的网页进行大量的爬取,那么可以初步判定为网络爬虫的自动爬取行为,该网站有可能会针对该IP的用户禁止访问。如果我们的IP被禁止访问了,就需要更换IP,对于普通用户来说IP资源可能会有限,那么怎么样才能有较多的IP呢?利用代理服务器我们可以获取不同的IP,所以此时我们可以获取多个代理服务器,将这些服务器的IP组成一个IP池,爬虫每次对网页进行爬取的时候,可以随机选择IP池中的一个IP进行访问。如需满足以上需求,须要几个重要步骤:

  1. 在settings文件中添加:
# IP池
IPPOOL = [
    {"ipaddr":"182.92.242.11:80"},
    {"ipaddr":"222.132.194.45:8118"},
    {"ipaddr":"114.239.146.29:808"},
    {"ipaddr":"114.239.148.97:808"}
]
  1. 中间件(即 middlewares.py,创建project时自动创建此文件)设置,将中间件原先代码清空,添加以下代码:
import scrapy
import random
from BanSpider.settings import IPPOOL
import scrapy.downloadermiddleware.httpproxy import HttpProxyMiddleware

class IPPools(HttpProxyMiddleware):
    def __init__(self,ip=""):
        self.ip = ip
    
    def process_request(self,request,spider):
        # 随机取出一个ip字典
        ipDict = random.choice(IPPOOL)
        request.meta["proxy"] = "http://"+ipDict["ipaddr"]

将此中间件添加到settings文件中:

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddleware.httpproxy.HttpProxyMiddleware':123,
    # 中间件middlewares中IPPools函数的路径,根据值排序
    'BanSpider.middlewares.IPPools':120
}

使用用户代理池

我们知道,网站服务器可以识别爬行时候用户代理信息,通过用户代理信息可以判断出我们使用的是什么浏览器、什么形式的客户端等。所以对方的网站服务器可以根据我们的User-Agent信息,对我们的爬行行为进行分析,以此来实现反爬虫处理。最为爬虫方,显然不希望就这样被封禁,为了避免这一类的禁止,我们可以使用用户代理池进行处理。如需满足以上需求,须要几个重要步骤:

  1. settings设置用户代理池
USER_POOL = [
    "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
]
  1. 创建一个下载中间件文件usermiddleware
import random
from BanSpider.settings import USER_POOL
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware

class UserMid(UserAgentMiddleware):
    def __init__(self,user=""):
        self.user = user
    
    def process_request(self,request,spider):
        user = random.choice(USER_POOL)
        request.headers.setdefault("User-Agent",user)

将此中间件添加到settings文件中:

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware':100,
    'BanSpider.usermiddleware.UserMid':99
}

ROBOTSTXT

有时我们进行网络爬虫时,会遇到这样的问题:

DEBUG:Forbidden by robots.txt

解决:
在settings文件中,找到ROBOTSTXT设置,将True改为False

ROBOTSTXT_OBEY = False

http://www.kler.cn/a/7380.html

相关文章:

  • WebSocket简易聊天室实现(有详细解释)
  • vue 模板语法 ( 插值表达式 | 属性绑定 | 双向数据绑定 | 指令 | 按键修饰符 )
  • 蓝桥杯每日真题 - 第15天
  • rust高级特征
  • STM32寄存器结构体详解
  • 51单片机基础05 定时器
  • 【vscode】检查到已经改正的错误,没有错误却检查到有错误
  • js跨域与解决
  • [GXYCTF2019]BabyUpload
  • 摸鱼也可以效率翻倍:Python 统计 gitlab 代码量,定量统计发给领导
  • Python3 os.isatty() 方法、Python3 os.dup2() 方法
  • Hadoop基础介绍
  • JetpackCompose从入门到实战学习笔记13——Compose中实现简单瀑布流
  • 基于html+css的内容旋转
  • Solon v2.2.7 发布,支持 Java 20
  • MLSkin 5.3 for delphi Crack
  • 约瑟夫问题
  • 【redis】redis分布式锁
  • 镜头光学指标介绍----清晰度SFR
  • 【从零开始学习 UVM】10.2、UVM TLM —— UVM TLM Blocking Put Port
  • 【CSAPP】进程 | 上下文切换 | 用户视角下的并发进程
  • 流量整形(GTS和LR)
  • 蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)
  • L2-040 哲哲打游戏 简单模拟
  • 免费CRM如何进行选择?
  • 用GPT-4写代码不用翻墙了?Cursor告诉你:可以~~