scrapy爬虫框架 (5. 避免被封措施)
文章目錄
- 1. 措施
- 2.Scrapy Middleware用法簡(jiǎn)介(下面幾個(gè)操作都需要用到這個(gè)文件)
- 2.1 文件位置
- 2.2 簡(jiǎn)介
- 轉(zhuǎn)自:https://www.cnblogs.com/onefine/p/10499320.html
- 3.隨機(jī)延時(shí)爬取
- 方式一:這個(gè)項(xiàng)目下的所有爬蟲(chóng)延時(shí)(已嘗試)
- 方式二:單獨(dú)spider延時(shí)(未嘗試)
- 1.首先了解scrapy項(xiàng)目中settings參數(shù)的使用詳解里的custom_settings
- 轉(zhuǎn)自:https://blog.csdn.net/he_ranly/article/details/85092065
- 2.實(shí)現(xiàn)
- 轉(zhuǎn)自:https://blog.csdn.net/mouday/article/details/81512748
- 4.禁止cookies
- 5.若不禁止cookies,就加上header和cookie
- 轉(zhuǎn)自:https://blog.csdn.net/sinat_41721615/article/details/99625952
- 5.1 方式一:cookies需要寫(xiě)成字典形式
- 5.2 方式二:cookies不需要寫(xiě)成字典形式
- 6. 隨機(jī)user-agent
- 6.1 手動(dòng)添加方式(未嘗試)
- 6.2 自動(dòng)方式,通過(guò)第三方庫(kù)隨機(jī)生成請(qǐng)求頭
- 6.2.1 標(biāo)準(zhǔn)用法(已嘗試)
- 6.2.2 簡(jiǎn)易用法,用在request中,不是scrapy
- 轉(zhuǎn)自:https://blog.csdn.net/qq_38251616/article/details/86751142
- 6.2.3 報(bào)錯(cuò)解決辦法:注意每次用前都要更新
- 7.ip池(目前用到的最大殺招)
- 7.0 ip小知識(shí)
- 7.1 代碼
- 7.2 問(wèn)題一:運(yùn)行爬蟲(chóng)后報(bào)10060或10061錯(cuò)誤,就是服務(wù)器積極拒絕或連接方 一段時(shí)間后沒(méi)有正確答復(fù)等,反正就是連接失敗
- 7.2.1 第一步嘗試:免費(fèi)ip網(wǎng)站尋找ip
- 7.2.2 第二步嘗試:網(wǎng)上自動(dòng)獲取可用id
- 7.2.3 最后懷疑是不是代碼問(wèn)題,因此買(mǎi)了一批ip,發(fā)現(xiàn)可以使用,那么報(bào)錯(cuò)就是一直沒(méi)有找到優(yōu)質(zhì)ip的原因,說(shuō)明免費(fèi)ip的網(wǎng)站質(zhì)量真是很差。。。
- 7.3 建立ip池
1. 措施
爬的太猖狂,容易被封ip。避免被封,就要采取一些措施
策略1:設(shè)置download_delay下載延遲,數(shù)字設(shè)置為5秒,越大越安全,老師說(shuō)15~90秒。。。
策略2:禁止Cookie,某些網(wǎng)站會(huì)通過(guò)Cookie識(shí)別用戶(hù)身份,禁用后使得服務(wù)器無(wú)法識(shí)別爬蟲(chóng)軌跡
策略3:使用user-agent池。也就是每次發(fā)送的時(shí)候隨機(jī)從池中選擇不一樣的瀏覽器頭信息,防止暴露爬蟲(chóng)身份
策略4:使用IP池,這個(gè)需要大量的IP資源,貌似還達(dá)不到這個(gè)要求
策略5:分布式爬取,這個(gè)是針對(duì)大型爬蟲(chóng)系統(tǒng)的,對(duì)目前而言我們還用不到(沒(méi)用過(guò))
策略6:偽造x-forward-for,偽裝自身為代理,讓服務(wù)器不認(rèn)為你是爬蟲(chóng)(沒(méi)用過(guò))
2.Scrapy Middleware用法簡(jiǎn)介(下面幾個(gè)操作都需要用到這個(gè)文件)
2.1 文件位置
2.2 簡(jiǎn)介
轉(zhuǎn)自:https://www.cnblogs.com/onefine/p/10499320.html
介紹:
Downloader Middleware即下載中間件,它是處于Scrapy的Request和Response之間的處理模塊。
Scheduler從隊(duì)列中拿出一個(gè)Request發(fā)送給Downloader執(zhí)行下載,這個(gè)過(guò)程會(huì)經(jīng)過(guò)Downloader Middleware的處理。另外,當(dāng)Downloader將Request下載完成得到Response返回給Spider時(shí)會(huì)再次經(jīng)過(guò)Downloader Middleware處理。
也就是說(shuō),Downloader Middleware在整個(gè)架構(gòu)中起作用的位置是以下兩個(gè):
1.在Scheduler調(diào)度出隊(duì)列的Request發(fā)送給Doanloader下載之前,也就是我們可以在Request執(zhí)行下載之前對(duì)其進(jìn)行修改。
2.在下載后生成的Response發(fā)送給Spider之前,也就是我們可以在生成Resposne被Spider解析之前對(duì)其進(jìn)行修改。
Downloader Middleware的功能十分強(qiáng)大,修改User-Agent、處理重定向、設(shè)置代理、失敗重試、設(shè)置Cookies等功能都需要借助它來(lái)實(shí)現(xiàn)。下面我們來(lái)了解一下Downloader Middleware的詳細(xì)用法。
3.隨機(jī)延時(shí)爬取
scrapy中有一個(gè)參數(shù):DOWNLOAD_DELAY 或者 download_delay 可以設(shè)置下載延時(shí),不過(guò)Spider類(lèi)被初始化的時(shí)候就固定了,爬蟲(chóng)運(yùn)行過(guò)程中沒(méi)發(fā)改變。
方式一:這個(gè)項(xiàng)目下的所有爬蟲(chóng)延時(shí)(已嘗試)
1.首先在middlewares.py里寫(xiě)
import random import time #延時(shí)爬取,隨機(jī)時(shí)間 class RandomDelayMiddleware(object):def __init__(self, delay):self.delay = delay@classmethoddef from_crawler(cls, crawler):delay = crawler.spider.settings.get("RANDOM_DELAY", 10)if not isinstance(delay, int):raise ValueError("RANDOM_DELAY need a int")return cls(delay)def process_request(self, request, spider):delay = random.randint(0, self.delay) #0到self.delay中隨機(jī)延時(shí),下面代碼設(shè)置的是3time.sleep(delay)2.然后在settings.py里寫(xiě)
#隨機(jī)下載延遲,這里延時(shí)3s,一般延時(shí)是15~90s RANDOM_DELAY = 33.最后在settings.py的DOWNLOADER_MIDDLEWARES里啟動(dòng)隨機(jī)延時(shí)
方式二:單獨(dú)spider延時(shí)(未嘗試)
1.首先了解scrapy項(xiàng)目中settings參數(shù)的使用詳解里的custom_settings
轉(zhuǎn)自:https://blog.csdn.net/he_ranly/article/details/85092065
custom_settings可以理解為spider的個(gè)性設(shè)置,通常我們?cè)谝粋€(gè)項(xiàng)目目錄下會(huì)有很多個(gè)spider,但是只有一個(gè)settings.py全局配置文件,為了讓不同的spider應(yīng)用不同的設(shè)置,我們可以在spider代碼中加入custom_settings設(shè)置。
例如:
spiders/somespider.py:
custom_settings.py:
custom_settings_for_spider1 = {'LOG_FILE': 'spider1.log','CONCURRENT_REQUESTS': 100,'DOWNLOADER_MIDDLEWARES': {'spider.middleware_for_spider1.Middleware': 667,},'ITEM_PIPELINES': {'spider.mysql_pipeline_for_spider1.Pipeline': 400,}, }custom_settings_for_spider2 = {'LOG_FILE': 'spider2.log','CONCURRENT_REQUESTS': 40,'DOWNLOADER_MIDDLEWARES': {'spider.middleware_for_spider2.Middleware': 667,},'ITEM_PIPELINES': {'spider.mysql_pipeline_for_spider2.Pipeline': 400,}, }在spider里有兩個(gè)蜘蛛spider1、spider2里,我們引入了來(lái)自custom_settings的配置變量custom_settings_for_spider1、custom_settings_for_spider2,通過(guò)這些變量,我們分別對(duì)兩個(gè)爬蟲(chóng)的log文件、并發(fā)數(shù)、應(yīng)用的中間件和管道文件進(jìn)行了設(shè)置。
custom_settings的優(yōu)先級(jí)在命令行以下,比settings.py要高。
2.實(shí)現(xiàn)
轉(zhuǎn)自:https://blog.csdn.net/mouday/article/details/81512748
1.middlewares.py的部分是一樣的,這里就是多了個(gè)日志打印
# -*- coding:utf-8 -*- import logging import random import timeclass RandomDelayMiddleware(object):def __init__(self, delay):self.delay = delay@classmethoddef from_crawler(cls, crawler):delay = crawler.spider.settings.get("RANDOM_DELAY", 10)if not isinstance(delay, int):raise ValueError("RANDOM_DELAY need a int")return cls(delay)def process_request(self, request, spider):delay = random.randint(0, self.delay)logging.debug("### random delay: %s s ###" % delay)time.sleep(delay)2.直接在spider里寫(xiě)
custom_settings = {"RANDOM_DELAY": 3,"DOWNLOADER_MIDDLEWARES": {"middlewares.random_delay_middleware.RandomDelayMiddleware": 999,} }具體位置是:
*******引入頭文件class Spider1(CrawlSpider):name = "spider1"custom_settings = {"RANDOM_DELAY": 3,"DOWNLOADER_MIDDLEWARES": {"middlewares.random_delay_middleware.RandomDelayMiddleware": 999,}}pass4.禁止cookies
上網(wǎng)搜‘瀏覽器禁止cookie’
5.若不禁止cookies,就加上header和cookie
轉(zhuǎn)自:https://blog.csdn.net/sinat_41721615/article/details/99625952
5.1 方式一:cookies需要寫(xiě)成字典形式
通過(guò)yield scrapy.Request(url=url, headers=headers, cookies=cookies, callback=self.parse)添加,也就是添加請(qǐng)求頭。
1.瀏覽器中cookies:
2.轉(zhuǎn)化為字典格式:
def transform(self,cookies):cookie_dict = {}cookies = cookies.replace(' ','')list = cookies.split(';')for i in list:keys = i.split('=')[0]values = i.split('=')[1]cookie_dict[keys] = valuesreturn cookie_dict3.因此headers和cookies是:
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'} cookies = {'_T_WM': '98075578786', 'WEIBOCN_WM': '3349', 'H5_wentry': 'H5', 'backURL': 'https%3A%2F%2Fm.weibo.cn%2Fdetail%2F4396824548695177', 'ALF': '1568417075', 'SCF': 'Ap5VqXy_BfNHBEUteiYtYDRa04jqF4QPJBULzWo7c1c_noO0GpnJW3BqhIkH7JXJSwWhL0qSg69_Vici5P7NbmY.', 'SUB': '_2A25wUOt6DeRhGeFM41AT9y3LyDSIHXVTuvUyrDV6PUJbktANLVXzkW1NQL_2tT4ZmobAs5b6HbIQwSRXHjjiRkzj', 'SUBP': '0033WrSXqPxfM725Ws9jqgMF55529P9D9WFWyDsTszIBJPBJ6gn7ccSM5JpX5K-hUgL.FoME1hzES0eNe0n2dJLoI0YLxK-L1K.L1KMLxK-L1KzLBoeLxK-L12BLBK2LxK-LBK-LB.BLxK-LBK-LB.BLxKnLB-qLBoBLxKnLB-qLBoBt', 'SUHB': '0S7CWHWuRz1aWf', 'SSOLoginState': '1565825835'}4.傳值:
yield scrapy.Request(url=url, headers=headers, cookies=cookies, callback=self.parse)??5、修改COOKIES_ENABLED
當(dāng)COOKIES_ENABLED是注釋的時(shí)候scrapy默認(rèn)沒(méi)有開(kāi)啟cookie
當(dāng)COOKIES_ENABLED沒(méi)有注釋設(shè)置為False的時(shí)候scrapy默認(rèn)使用了settings里面的cookie
當(dāng)COOKIES_ENABLED設(shè)置為T(mén)rue的時(shí)候scrapy就會(huì)把settings的cookie關(guān)掉,使用自定義cookie
所以需要在settings.py文件中設(shè)置COOKIES_ENABLED = True?
并且在settings.py文件中設(shè)置ROBOTSTXT_OBEY = False? #不遵守robotstxt協(xié)議
5.2 方式二:cookies不需要寫(xiě)成字典形式
在setting.py文件中添加cookies與headers — 最簡(jiǎn)單的方法
1.settings文件中給Cookies_enabled=False和DEFAULT_REQUEST_HEADERS解注釋
2.在settings的DEFAULT_REQUEST_HEADERS配置的cookie就可以使用了
6. 隨機(jī)user-agent
6.1 手動(dòng)添加方式(未嘗試)
User Agent中文名為用戶(hù)代理,簡(jiǎn)稱(chēng) UA,它是一個(gè)特殊字符串頭,使得服務(wù)器能夠識(shí)別客戶(hù)使用的操作系統(tǒng)及版本、CPU 類(lèi)型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語(yǔ)言、瀏覽器插件等,因此不同瀏覽器的user-agent不同。
1.可以把多個(gè)User-Agent作為一個(gè)配置在setting文件中
然后再編寫(xiě)middlewares.py
class RandomUserAgentMiddleware(object):def __init__(self, crawler):super(RandomUserAgentMiddleware, self).__init__()self.user_agent_list = crawler.get("user_agent_list", [])@classmethoddef from_crawler(cls, crawler):return cls(crawler)def process_request(self, request, spider):#方法一:需要在settings中將系統(tǒng)默認(rèn)的請(qǐng)求頭禁掉request.headers.setdefault("User-Agent", random.choice(self.user_agent_list))#方法二:不需要在settings中禁request.headers['User-Agent'] = random.choice(self.user_agent_list)最后在settings.py中設(shè)置DOWNLOAD_MIDDLEWARES,將系統(tǒng)默認(rèn)的隨機(jī)請(qǐng)求頭給禁掉,再添加我們自己定義的隨機(jī)UserAgent,對(duì)應(yīng)上面代碼process_request中的第一個(gè)方法
6.2 自動(dòng)方式,通過(guò)第三方庫(kù)隨機(jī)生成請(qǐng)求頭
通過(guò)pip install fake-useragent,從而直接通過(guò)fake_useragent第三方庫(kù)來(lái)隨機(jī)生成請(qǐng)求頭.
??下載好后記得導(dǎo)入
最開(kāi)始看的:https://www.cnblogs.com/qingchengzi/p/9633616.html
6.2.1 標(biāo)準(zhǔn)用法(已嘗試)
1.middlewares.py中:
from fake_useragent import UserAgent #隨機(jī)更換user-agent class RandomUserAgentMiddlware(object):'''隨機(jī)更換user-agent,基本上都是固定格式和scrapy源碼中useragetn.py中UserAgentMiddleware類(lèi)中一致'''def __init__(self,crawler):super(RandomUserAgentMiddlware,self).__init__()self.ua = UserAgent()#從配置文件settings中讀取RANDOM_UA_TYPE值,默認(rèn)為random,可以在settings中自定義self.ua_type = crawler.settings.get("RANDOM_UA_TYPE","random")@classmethoddef from_crawler(cls,crawler):return cls(crawler)def process_request(self,request,spider):#必須和內(nèi)置的一致,這里必須這樣寫(xiě)def get_ua():return getattr(self.ua,self.ua_type)request.headers.setdefault('User-Agent',get_ua())2.首先我們?cè)趕etting配置文件中設(shè)置一個(gè)變量RANDOM_UA_TYPE,它的功能是可以按照我們自己配置的值來(lái)選擇useragent。并且再把系統(tǒng)的禁掉,啟動(dòng)自己的
RANDOM_UA_TYPE:
因此最終settings:
6.2.2 簡(jiǎn)易用法,用在request中,不是scrapy
轉(zhuǎn)自:https://blog.csdn.net/qq_38251616/article/details/86751142
安裝成功后,我們每次發(fā)送requests請(qǐng)求時(shí)通過(guò)random從中隨機(jī)獲取一個(gè)隨機(jī)UserAgent,兩行代碼即可完成UserAgent的不停更換。
from fake_useragent import UserAgent headers= {'User-Agent':str(UserAgent().random)} r = requests.get(url, proxies=proxies, headers=headers, timeout=10)6.2.3 報(bào)錯(cuò)解決辦法:注意每次用前都要更新
我在使用fake_useragent中遇到如下的報(bào)錯(cuò),在起初誤認(rèn)為是部分網(wǎng)站對(duì)某些UserAgent的屏蔽導(dǎo)致的fake_useragent調(diào)用出錯(cuò),后來(lái)追究下來(lái)發(fā)現(xiàn)是由于fake_useragent中存儲(chǔ)的UserAgent列表發(fā)生了變動(dòng),而我本地UserAgent的列表未更新所導(dǎo)致的,在更新fake_useragent后報(bào)錯(cuò)就消失了。
fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached更新fake_useragent,在命令行中輸入pip install -U fake-useragent即可完成更新,Python的其他包也可以用這種方法完成更新pip install -U 包名。
7.ip池(目前用到的最大殺招)
7.0 ip小知識(shí)
(1) 透明代理
代理服務(wù)器將客戶(hù)端的信息轉(zhuǎn)發(fā)至目標(biāo)訪問(wèn)對(duì)象,并沒(méi)有完全隱藏客戶(hù)端真實(shí)的身份。即服務(wù)器知道客戶(hù)端使用了代理IP,并且知道客戶(hù)端的真實(shí)IP地址。
(2) 普通匿名代理
代理服務(wù)器用自己的IP代替了客戶(hù)端的真實(shí)IP,但是告訴了目標(biāo)訪問(wèn)對(duì)象這是代理訪問(wèn)。
(3) 高匿代理
代理服務(wù)器良好地偽裝了客戶(hù)端,不但用一個(gè)隨機(jī)的IP代替了客戶(hù)端的IP,也隱藏了代理信息,服務(wù)器不會(huì)察覺(jué)到客戶(hù)端是通過(guò)代理實(shí)現(xiàn)訪問(wèn)的,即用戶(hù)仿佛就是直接使用代理服務(wù)器作為自己的客戶(hù)端,618國(guó)內(nèi)IP代理就是高匿名的服務(wù)器。
所以使用高匿代理就可以隱藏自己的真實(shí)IP了
7.1 代碼
1.setttings設(shè)置ip池:
ip是否可以使用可以用ip質(zhì)量檢查網(wǎng)站檢查:http://www.jsons.cn/ping/
2.middlewares.py中添加:
3.settings的DOWNLOADER_MIDDLEWARES中開(kāi)啟
7.2 問(wèn)題一:運(yùn)行爬蟲(chóng)后報(bào)10060或10061錯(cuò)誤,就是服務(wù)器積極拒絕或連接方 一段時(shí)間后沒(méi)有正確答復(fù)等,反正就是連接失敗
7.2.1 第一步嘗試:免費(fèi)ip網(wǎng)站尋找ip
出現(xiàn)這種問(wèn)題就是IP的問(wèn)題,換一批就好,因此我在下面的網(wǎng)站中找了一批又一批ip:
快代理、89免費(fèi)代理、66免費(fèi)代理、西刺代理
但是一直找不到能用的。。。
7.2.2 第二步嘗試:網(wǎng)上自動(dòng)獲取可用id
轉(zhuǎn)自:https://www.jianshu.com/p/8449b9c397bb
自動(dòng)把成功的id放到proxies.txt中,但是用了成功的id還是不行
7.2.3 最后懷疑是不是代碼問(wèn)題,因此買(mǎi)了一批ip,發(fā)現(xiàn)可以使用,那么報(bào)錯(cuò)就是一直沒(méi)有找到優(yōu)質(zhì)ip的原因,說(shuō)明免費(fèi)ip的網(wǎng)站質(zhì)量真是很差。。。
7.3 建立ip池
傳送門(mén)
總結(jié)
以上是生活随笔為你收集整理的scrapy爬虫框架 (5. 避免被封措施)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 面向对象核心技术
- 下一篇: [论文阅读]A Joint Traini