Scrapy 爬虫中的机器人协议和爬虫限制:如何遵守机器人协议和应对爬虫限制?
机器人协议是指网站所有者发布的爬虫行为规范,旨在保护网站的正常运营和用户权益。在使用 Scrapy 爬虫时,遵守机器人协议是非常重要的,否则网站可能会屏蔽该爬虫的请求。本文将分为两部分介绍如何遵守机器人协议和应对爬虫限制,同时提供代码演示。
一、遵守机器人协议
- 查看 robots.txt 文件
robots.txt 文件是每个网站所有者都可以发布的机器人协议文件,该文件告诉爬虫程序哪些页面可以被访问,哪些页面禁止访问。通常,在 Scrapy 爬虫开始前,需要检查目标网站的 robots.txt 文件,并根据协议里的规定进行爬取。
以下是查看 robots.txt 文件的示例代码:
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def parse_item(self, response): # 检查 robots.txt 文件 robots_url = response.urljoin('/robots.txt') yield scrapy.Request(robots_url, callback=self.parse_robots) def parse_robots(self, response): # 查看 robots.txt 文件 print(response.text) # 根据协议爬取数据 pass
- 设置 User-Agent
User-Agent 是 HTTP 请求头中的一项参数,用于标记请求方的软件系统和版本等信息。很多网站会根据 User-Agent 判断请求方是否为爬虫程序,因此设置合适的 User-Agent 是遵守机器人协议的重要步骤。
以下是设置 User-Agent 的示例代码:
class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def start_requests(self): # 设置 User-Agent user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' for url in self.start_urls: yield scrapy.Request(url, headers={'User-Agent': user_agent}) def parse_item(self, response): # 解析页面数据 pass
- 控制访问速度
在进行爬取时,爬虫程序发送的请求速度过快容易让网站担心自己的网络资源被耗费。因此,常常需要在爬虫中进行访问速度控制。可以在 Scrapy 中使用 DOWNLOAD_DELAY 配置项对访问速度进行控制。
以下是控制访问速度的示例代码:
class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] download_delay = 0.5 # 每次访问间隔 0.5 秒 rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def parse_item(self, response): # 解析页面数据 pass
二、应对爬虫限制
- 处理状态码
在爬取过程中,常常会遇到一些被限制的情况,例如网站屏蔽爬虫的请求或者返回状态码 503(服务器过载)等。在这些情况下,需要让爬虫处理相应的状态码并采取相应的策略。
以下是处理状态码的示例代码:
class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def parse_item(self, response): if response.status == 503: # 重试请求 yield response.request.copy() if response.status == 403: # 输出错误信息 self.logger.error('Access denied! Url: %s', response.url) # 解析页面数据 pass
- 使用代理 IP
网站为了防止爬虫程序的攻击,有时会限制来自同一 IP 地址的请求频率。因此,使用代理 IP 是应对爬虫限制的常用方法之一。
以下是使用代理 IP 的示例代码:
class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] proxies = ["http://10.10.1.10:3128", "http://10.10.1.11:1080"] rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def start_requests(self): for url in self.start_urls: # 设置代理 IP for proxy in self.proxies: yield scrapy.Request(url, meta={'proxy': proxy}) def parse_item(self, response): # 解析页面数据 pass
- 使用随机 User-Agent
有些网站会根据 User-Agent 限制请求,因此使用随机 User-Agent 是一种有效应对爬虫限制的方法。可以在 Scrapy 中通过配置 DOWNLOADER_MIDDLEWARES 配置项来实现。
以下是使用随机 User-Agent 的示例代码:
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware import random class RandomUserAgentMiddleware(UserAgentMiddleware): def __init__(self, settings, user_agent='Scrapy'): super().__init__(user_agent) self.user_agents = settings.getlist('USER_AGENTS') @classmethod def from_crawler(cls, crawler): return cls(crawler.settings, crawler.settings.get('USER_AGENT')) def process_request(self, request, spider): # 随机 User-Agent request.headers.setdefault('User-Agent', random.choice(self.user_agents)) class DemoSpider(CrawlSpider): name = 'demo' allowed_domains = ['pidancode.com'] start_urls = ['https://www.pidancode.com'] custom_settings = { 'DOWNLOADER_MIDDLEWARES': { 'project.middlewares.RandomUserAgentMiddleware': 543, }, 'USER_AGENTS': [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36', 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko', ], } rules = ( Rule(LinkExtractor(), callback='parse_item', follow=True), ) def parse_item(self, response): # 解析页面数据 pass
通过以上方法,能够有效遵守机器人协议并应对爬虫限制,保证爬虫程序的正常工作。
相关文章