Scrapy框架03【反爬,及反反爬措施,图片下载器】
反爬
1.反爬虫的原因
- 降低服务器负载
-
爬虫占用服务器资源,影响正常用户
- 假设服务器同时可以接受10个请求,一个爬虫就可以利用多线程全部占用
- 维护企业的竞争力
2.常见反爬的三个方向
- 判断用户身份
-
User-Agent ·
-
Cookies ·
-
Refer ·
-
验证码 ·
-
- 分析用户行为
- 通过并发识别爬虫 ·
- 在线活动时间 ·
- 页面添加一些正常浏览器浏览访问不到的资源
- 动态加载数据
- js
- ajax
scrapy反爬应对与下载器中间件
Scrapy常见反反爬措施
- 1)模拟用户头 设置位置:
- ①settings文件
- ②创建请求时
- ③下载器中间件
- 2)请求延迟
- settings文件中 DOWNLOAD_DELAY = n 测试目标站点阈值后设置
- 3)Cookies检测
- settings文件中 COOKIES_ENABLED = False
- 4)使用ip代理池
- 中间件里设置
-
除了官方的crawlera代理其余的都需要在下载器中间件中设置ip代理
通常防止爬虫被反主要有以下几个策略:
-
动态设置User-Agent(随机切换User-Agent,模拟不同用户的浏览器信息)
-
禁用Cookies(也就是不启用cookies middleware,不向Server发送cookies,有些网站通过cookie的使用发现爬虫行为)
- 可以通过
COOKIES_ENABLED控制 CookiesMiddleware 开启或关闭
- 可以通过
-
设置延迟下载(防止访问过于频繁,设置为 2秒 或更高)
-
Google Cache 和 Baidu Cache:如果可能的话,使用谷歌/百度等搜索引擎服务器页面缓存获取页面数据。
-
使用IP地址池:VPN和代理IP,现在大部分网站都是根据IP来ban的。
-
使用 Crawlerahttps://scrapinghub.com/crawlera(专用于爬虫的代理组件),正确配置和设置下载中间件后,项目所有的request都是通过crawlera发出。
DOWNLOADER_MIDDLEWARES = {
'scrapy_crawlera.CrawleraMiddleware': 600
}
CRAWLERA_ENABLED = True
CRAWLERA_USER = '注册/购买的UserKey'
CRAWLERA_PASS = '注册/购买的Password'
设置下载中间件(Downloader Middlewares)
激活下载器中间件组件
DOWNLOADER_MIDDLEWARES = {
'mySpider.middlewares.MyDownloaderMiddleware': 543,
}
setting配置
Scrapy设置(settings)提供了定制Scrapy组件的方法。可以控制包括核心(core),插件(extension),pipeline及spider组件。比如 设置Json Pipeliine、LOG_LEVEL等。
参考文档:http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/settings.html#topics-settings-ref
内置设置参考手册
-
BOT_NAME-
默认: 'scrapybot'
-
当您使用 startproject 命令创建项目时其也被自动赋值。
-
-
CONCURRENT_ITEMS-
默认: 100
-
Item Processor(即 Item Pipeline) 同时处理(每个response的)item的最大值。
-
-
CONCURRENT_REQUESTS-
默认: 16
-
Scrapy downloader 并发请求(concurrent requests)的最大值。
-
-
DEFAULT_REQUEST_HEADERS-
默认: 如下
{ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en', }Scrapy HTTP Request使用的默认header。
-
-
DEPTH_LIMIT-
默认: 0
-
爬取网站最大允许的深度(depth)值。如果为0,则没有限制。
-
-
DOWNLOAD_DELAY-
默认: 0
-
下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。同时也支持小数:
DOWNLOAD_DELAY = 0.25 # 250 ms of delay
- 默认情况下,Scrapy在两个请求间不等待一个固定的值, 而是使用0.5到1.5之间的一个随机值 * DOWNLOAD_DELAY 的结果作为等待间隔。
-
-
DOWNLOAD_TIMEOUT-
默认: 180
-
下载器超时时间(单位: 秒)。
-
-
ITEM_PIPELINES-
默认: {}
-
保存项目中启用的pipeline及其顺序的字典。该字典默认为空,值(value)任意,不过值(value)习惯设置在0-1000范围内,值越小优先级越高。
ITEM_PIPELINES = { 'mySpider.pipelines.SomethingPipeline': 300, 'mySpider.pipelines.ItcastJsonPipeline': 800, }
-
-
LOG_ENABLED-
默认: True
-
是否启用logging。 运行时 是否打印log信息
-
-
LOG_ENCODING-
默认: 'utf-8'
-
logging使用的编码。显示log日志的编码格式
-
- LOG_FILE
- 生成log文件
- LOG_FILE = 'mylog.log'
-
LOG_LEVEL-
默认: 'DEBUG'
- 设置格式为
-
LOG_LEVEL = "INFO" #
-
log的最低级别。可选的级别有:
-
CRITICAL - 严重错误(critical)
-
ERROR - 一般错误(regular errors)
-
WARNING - 警告信息(warning messages) 一般除警告错误不会打印
-
INFO - 一般信息(informational messages) 打印爬虫返回的数据 及引擎返回的数据
-
DEBUG - 调试信息(debugging messages)
-
-
- LOG_FILE
- log文件路径
-
USER_AGENT-
默认:
-
"Scrapy/VERSION (+http://scrapy.org)"
-
爬取的默认User-Agent,除非被覆盖。
-
-
PROXIES: 代理设置-
示例:
PROXIES = [ {'ip_port': '111.11.228.75:80', 'password': ''}, {'ip_port': '120.198.243.22:80', 'password': ''}, {'ip_port': '111.8.60.9:8123', 'password': ''}, {'ip_port': '101.71.27.120:80', 'password': ''}, {'ip_port': '122.96.59.104:80', 'password': ''}, {'ip_port': '122.224.249.122:8088', 'password':''}, ]
-
-
COOKIES_ENABLED = False- 禁用Cookies
#CONCURRENT_REQUESTS_PER_DOMAIN = 16 # 对同一个域名同时有多少个请求 #CONCURRENT_REQUESTS_PER_IP = 16 # 每一ip的并发数量
在配置文件中设置路径
IMAGES_STORE = '/home/python/Desktop/Spider/day06-框架豆瓣电影_斗鱼妹子/Douban/Douban'
import os import scrapy # 三种导入setting文件的方法 from scrapy.utils.project import get_project_settings from Itcast.settings import IMAGES_STORE from scrapy.conf import settings # 导入该类 from scrapy.pipelines.images import ImagesPipeline class xxxxPipeline(object): def process_item(self, item, spider): return item class ImagePipeline(ImagesPipeline): IMAGES_STORE = get_project_settings().get('IMAGES_STORE') def get_media_requests(self, item, info): # 获取照片并保存到setting指定的路径 # print(self.IMAGES_STORE) yield scrapy.Request(url=item['img_url']) # print('-'*88) def item_completed(self, results, item, info): # results会把保存的信息返回 可以对下载的文件名进行操作 以下为修改照片名字的案例 img_path = [data["path"] for ok, data in results] # 旧 old_path = self.IMAGES_STORE + os.sep + img_path[0] # 新 new_path = self.IMAGES_STORE + os.sep + img_path[0].split('/')[0] + os.sep + item["name"] +'.jpg' # 换路径 os.rename(old_path, new_path) return item

浙公网安备 33010602011771号