1、更换User-Agent
在每个请求中使用不同的User-Agent,以避免被服务器检测到爬虫行为。可以创建一个随机选择User-Agent的下载中间件,并在settings.py文件中启用该中间件。
import random
from scrapy import signals
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
class RandomUserAgentMiddleware(UserAgentMiddleware):
def __init__(self, user_agent_list):
self.user_agent_list = user_agent_list
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings.get('USER_AGENT_LIST'))
crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
return s
def process_request(self, request, spider):
ua = random.choice(self.user_agent_list)
if ua:
request.headers.setdefault('User-Agent', ua)
def spider_closed(self, spider):
pass
2、添加Referer信息:
在每个请求中添加Referer头部信息,以让服务器认为你是从其他页面转跳过来的,而不是直接发送了请求。可以创建一个随机选择Referer值的下载中间件,并在settings.py文件中启用该中间件。
import random
from scrapy import signals
class RandomRefererMiddleware():
def __init__(self, referer_list):
self.referer_list = referer_list
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings.get('REFERER_LIST'))
crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
return s
def process_request(self, request, spider):
referer = random.choice(self.referer_list)
if referer:
request.headers.setdefault('Referer', referer)
def spider_closed(self, spider):
pass
3、模拟鼠标移动:
在请求中添加Mouse-Event信息,以模拟鼠标移动的行为。可以使用selenium或webdrive等工具来实现这个功能。
from selenium.webdriver import ActionChains
class MySpider(Spider):
name = 'myspider'
start_urls = ['http://www.example.com']
def parse(self, response):
# 获取selenium的浏览器驱动对象
driver = response.meta['driver']
# 模拟鼠标移动到某个元素上
element = driver.find_element_by_xpath('//div[@class="example"]')
action_chains = ActionChains(driver)
action_chains.move_to_element(element).perform()
# ...
4、随机化请求参数:
随机生成一些参数(如时间戳、session ID、nonce等)并将它们添加到请求中,以避免过于固定和预测的请求行为。可以创建一个随机生成这些参数的下载中间件,并在settings.py文件中启用该中间件。
import random
import time
from scrapy import signals
class RandomParamsMiddleware():
def __init__(self, params_list):
self.params_list = params_list
@classmethod
def from_crawler(cls, crawler):
s = cls(crawler.settings.get('PARAMS_LIST'))
crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
return s
def process_request(self, request, spider):
params = random.choice(self.params_list)
if params:
for key, value in params.items():
request.headers.setdefault(key, value)
def spider_closed(self, spider):
pass
5、随机化请求间隔时间:
在每个请求之间增加随机的间隔时间,以避免过于规律和频繁的请求行为。可以通过设置DOWNLOAD_DELAY来实现这一点,或者使用类似于time.sleep(random.uniform(0, 5))的代码来实现更加灵活的间隔时间设置。
class MySpider(Spider):
name = 'myspider'
start_urls = ['http://www.example.com']
download_delay = 0.5 # 设置每个请求之间的延迟为0.5秒
def parse(self, response):
# ...
6、模拟登陆操作:
对于需要登陆才能访问的网站,可以模拟登陆操作以获取访问权限。可以使用selenium或webdrive等工具来模拟登陆操作,并在爬虫中保持登陆状态(如使用scrapy-cookies库来管理cookies)。
from selenium.webdriver.common.keys import Keys
from scrapy.http import HtmlResponse
from scrapy.utils.python import to_bytes
class MySpider(Spider):
name = 'myspider'
login_url = 'http://www.example.com/login'
username = 'your_username'
password = 'your_password'
def start_requests(self):
yield SeleniumRequest(
url=self.login_url,
callback=self.login,
dont_filter=True
)
def login(self, response):
driver = response.meta['driver']
# 输入用户名密码并提交表单
username_input = driver.find_element_by_xpath('//input[@name="username"]')
password_input = driver.find_element_by_xpath('//input[@name="password"]')
username_input.send_keys(self.username)
password_input.send_keys(self.password)
password_input.send_keys(Keys.ENTER)
# 等待表单提交完成
time.sleep(5)
# 检查是否成功登陆
if 'Welcome' in driver.title:
self.logger.info('Login success!')
# 将cookies保存下来,以在后续请求中保持登陆状态
cookies = driver.get_cookies()
return [HtmlResponse(
url=driver.current_url,
body=to_bytes(driver.page_source),
encoding='utf-8',
request=response.request,
cookies=cookies
)]
else:
self.logger.error('Login failed!')
以上这些方法和代码示例可以帮助你模拟人类正常操作行为,从而避免被目标服务器检测到爬虫行为,并提高网站的爬取成功率。