日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

scrapy爬虫框架 (5. 避免被封措施)

發布時間:2024/3/12 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 scrapy爬虫框架 (5. 避免被封措施) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1. 措施
  • 2.Scrapy Middleware用法簡介(下面幾個操作都需要用到這個文件)
    • 2.1 文件位置
    • 2.2 簡介
      • 轉自:https://www.cnblogs.com/onefine/p/10499320.html
  • 3.隨機延時爬取
    • 方式一:這個項目下的所有爬蟲延時(已嘗試)
    • 方式二:單獨spider延時(未嘗試)
      • 1.首先了解scrapy項目中settings參數的使用詳解里的custom_settings
        • 轉自:https://blog.csdn.net/he_ranly/article/details/85092065
      • 2.實現
        • 轉自:https://blog.csdn.net/mouday/article/details/81512748
  • 4.禁止cookies
  • 5.若不禁止cookies,就加上header和cookie
    • 轉自:https://blog.csdn.net/sinat_41721615/article/details/99625952
    • 5.1 方式一:cookies需要寫成字典形式
    • 5.2 方式二:cookies不需要寫成字典形式
  • 6. 隨機user-agent
    • 6.1 手動添加方式(未嘗試)
    • 6.2 自動方式,通過第三方庫隨機生成請求頭
      • 6.2.1 標準用法(已嘗試)
      • 6.2.2 簡易用法,用在request中,不是scrapy
        • 轉自:https://blog.csdn.net/qq_38251616/article/details/86751142
      • 6.2.3 報錯解決辦法:注意每次用前都要更新
  • 7.ip池(目前用到的最大殺招)
    • 7.0 ip小知識
    • 7.1 代碼
    • 7.2 問題一:運行爬蟲后報10060或10061錯誤,就是服務器積極拒絕或連接方 一段時間后沒有正確答復等,反正就是連接失敗
      • 7.2.1 第一步嘗試:免費ip網站尋找ip
      • 7.2.2 第二步嘗試:網上自動獲取可用id
      • 7.2.3 最后懷疑是不是代碼問題,因此買了一批ip,發現可以使用,那么報錯就是一直沒有找到優質ip的原因,說明免費ip的網站質量真是很差。。。
    • 7.3 建立ip池

1. 措施

爬的太猖狂,容易被封ip。避免被封,就要采取一些措施
策略1:設置download_delay下載延遲,數字設置為5秒,越大越安全,老師說15~90秒。。。
策略2:禁止Cookie,某些網站會通過Cookie識別用戶身份,禁用后使得服務器無法識別爬蟲軌跡
策略3:使用user-agent池。也就是每次發送的時候隨機從池中選擇不一樣的瀏覽器頭信息,防止暴露爬蟲身份
策略4:使用IP池,這個需要大量的IP資源,貌似還達不到這個要求
策略5:分布式爬取,這個是針對大型爬蟲系統的,對目前而言我們還用不到(沒用過)
策略6:偽造x-forward-for,偽裝自身為代理,讓服務器不認為你是爬蟲(沒用過)

2.Scrapy Middleware用法簡介(下面幾個操作都需要用到這個文件)

2.1 文件位置

2.2 簡介

轉自:https://www.cnblogs.com/onefine/p/10499320.html

介紹:
Downloader Middleware即下載中間件,它是處于Scrapy的Request和Response之間的處理模塊。

Scheduler從隊列中拿出一個Request發送給Downloader執行下載,這個過程會經過Downloader Middleware的處理。另外,當Downloader將Request下載完成得到Response返回給Spider時會再次經過Downloader Middleware處理。

也就是說,Downloader Middleware在整個架構中起作用的位置是以下兩個:
1.在Scheduler調度出隊列的Request發送給Doanloader下載之前,也就是我們可以在Request執行下載之前對其進行修改。
2.在下載后生成的Response發送給Spider之前,也就是我們可以在生成Resposne被Spider解析之前對其進行修改。

Downloader Middleware的功能十分強大,修改User-Agent、處理重定向、設置代理、失敗重試、設置Cookies等功能都需要借助它來實現。下面我們來了解一下Downloader Middleware的詳細用法。

3.隨機延時爬取

scrapy中有一個參數:DOWNLOAD_DELAY 或者 download_delay 可以設置下載延時,不過Spider類被初始化的時候就固定了,爬蟲運行過程中沒發改變。

方式一:這個項目下的所有爬蟲延時(已嘗試)

1.首先在middlewares.py里寫

import random import time #延時爬取,隨機時間 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中隨機延時,下面代碼設置的是3time.sleep(delay)

2.然后在settings.py里寫

#隨機下載延遲,這里延時3s,一般延時是15~90s RANDOM_DELAY = 3

3.最后在settings.py的DOWNLOADER_MIDDLEWARES里啟動隨機延時

方式二:單獨spider延時(未嘗試)

1.首先了解scrapy項目中settings參數的使用詳解里的custom_settings

轉自:https://blog.csdn.net/he_ranly/article/details/85092065

custom_settings可以理解為spider的個性設置,通常我們在一個項目目錄下會有很多個spider,但是只有一個settings.py全局配置文件,為了讓不同的spider應用不同的設置,我們可以在spider代碼中加入custom_settings設置。
例如:
spiders/somespider.py:

from ..custom_settings import *class Spider1(CrawlSpider):name = "spider1"custom_settings = custom_settings_for_spider1passclass Spider2(CrawlSpider):name = "spider2"custom_settings = custom_settings_for_spider2

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里有兩個蜘蛛spider1、spider2里,我們引入了來自custom_settings的配置變量custom_settings_for_spider1、custom_settings_for_spider2,通過這些變量,我們分別對兩個爬蟲的log文件、并發數、應用的中間件和管道文件進行了設置。

custom_settings的優先級在命令行以下,比settings.py要高。

2.實現

轉自:https://blog.csdn.net/mouday/article/details/81512748

1.middlewares.py的部分是一樣的,這里就是多了個日志打印

# -*- 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里寫

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,}}pass

4.禁止cookies

上網搜‘瀏覽器禁止cookie’

5.若不禁止cookies,就加上header和cookie

轉自:https://blog.csdn.net/sinat_41721615/article/details/99625952

5.1 方式一:cookies需要寫成字典形式

通過yield scrapy.Request(url=url, headers=headers, cookies=cookies, callback=self.parse)添加,也就是添加請求頭。
1.瀏覽器中cookies:

Cookie:_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

2.轉化為字典格式:

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_dict

3.因此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

當COOKIES_ENABLED是注釋的時候scrapy默認沒有開啟cookie
當COOKIES_ENABLED沒有注釋設置為False的時候scrapy默認使用了settings里面的cookie
當COOKIES_ENABLED設置為True的時候scrapy就會把settings的cookie關掉,使用自定義cookie
所以需要在settings.py文件中設置COOKIES_ENABLED = True?

并且在settings.py文件中設置ROBOTSTXT_OBEY = False? #不遵守robotstxt協議

5.2 方式二:cookies不需要寫成字典形式

在setting.py文件中添加cookies與headers — 最簡單的方法

1.settings文件中給Cookies_enabled=False和DEFAULT_REQUEST_HEADERS解注釋
2.在settings的DEFAULT_REQUEST_HEADERS配置的cookie就可以使用了

6. 隨機user-agent

6.1 手動添加方式(未嘗試)

User Agent中文名為用戶代理,簡稱 UA,它是一個特殊字符串頭,使得服務器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等,因此不同瀏覽器的user-agent不同。
1.可以把多個User-Agent作為一個配置在setting文件中

user_agent_list = ["ua1","ua2","ua3", ]

然后再編寫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中將系統默認的請求頭禁掉request.headers.setdefault("User-Agent", random.choice(self.user_agent_list))#方法二:不需要在settings中禁request.headers['User-Agent'] = random.choice(self.user_agent_list)

最后在settings.py中設置DOWNLOAD_MIDDLEWARES,將系統默認的隨機請求頭給禁掉,再添加我們自己定義的隨機UserAgent,對應上面代碼process_request中的第一個方法

6.2 自動方式,通過第三方庫隨機生成請求頭

通過pip install fake-useragent,從而直接通過fake_useragent第三方庫來隨機生成請求頭.
??下載好后記得導入

最開始看的:https://www.cnblogs.com/qingchengzi/p/9633616.html

6.2.1 標準用法(已嘗試)

1.middlewares.py中:

from fake_useragent import UserAgent #隨機更換user-agent class RandomUserAgentMiddlware(object):'''隨機更換user-agent,基本上都是固定格式和scrapy源碼中useragetn.py中UserAgentMiddleware類中一致'''def __init__(self,crawler):super(RandomUserAgentMiddlware,self).__init__()self.ua = UserAgent()#從配置文件settings中讀取RANDOM_UA_TYPE值,默認為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):#必須和內置的一致,這里必須這樣寫def get_ua():return getattr(self.ua,self.ua_type)request.headers.setdefault('User-Agent',get_ua())

2.首先我們在setting配置文件中設置一個變量RANDOM_UA_TYPE,它的功能是可以按照我們自己配置的值來選擇useragent。并且再把系統的禁掉,啟動自己的
RANDOM_UA_TYPE:

# 隨機選擇UA RANDOM_UA_TYPE = "random" # 只選擇ie的UA RANDOM_UA_TYPE = "ie"

因此最終settings:

6.2.2 簡易用法,用在request中,不是scrapy

轉自:https://blog.csdn.net/qq_38251616/article/details/86751142

安裝成功后,我們每次發送requests請求時通過random從中隨機獲取一個隨機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 報錯解決辦法:注意每次用前都要更新

我在使用fake_useragent中遇到如下的報錯,在起初誤認為是部分網站對某些UserAgent的屏蔽導致的fake_useragent調用出錯,后來追究下來發現是由于fake_useragent中存儲的UserAgent列表發生了變動,而我本地UserAgent的列表未更新所導致的,在更新fake_useragent后報錯就消失了。

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小知識

(1) 透明代理
代理服務器將客戶端的信息轉發至目標訪問對象,并沒有完全隱藏客戶端真實的身份。即服務器知道客戶端使用了代理IP,并且知道客戶端的真實IP地址。
(2) 普通匿名代理
代理服務器用自己的IP代替了客戶端的真實IP,但是告訴了目標訪問對象這是代理訪問。
(3) 高匿代理
代理服務器良好地偽裝了客戶端,不但用一個隨機的IP代替了客戶端的IP,也隱藏了代理信息,服務器不會察覺到客戶端是通過代理實現訪問的,即用戶仿佛就是直接使用代理服務器作為自己的客戶端,618國內IP代理就是高匿名的服務器。
所以使用高匿代理就可以隱藏自己的真實IP了

7.1 代碼

1.setttings設置ip池:
ip是否可以使用可以用ip質量檢查網站檢查:http://www.jsons.cn/ping/

2.middlewares.py中添加:

import scrapy import random #代理ip池,隨機更換ip class ProxyMiddleware(object):# 設置Proxydef __init__(self, ip):self.ip = ip@classmethoddef from_crawler(cls, crawler):return cls(ip=crawler.settings.get('PROXIES'))def process_request(self, request, spider):ip = random.choice(self.ip)request.meta['proxy'] = ip

3.settings的DOWNLOADER_MIDDLEWARES中開啟

7.2 問題一:運行爬蟲后報10060或10061錯誤,就是服務器積極拒絕或連接方 一段時間后沒有正確答復等,反正就是連接失敗

7.2.1 第一步嘗試:免費ip網站尋找ip

出現這種問題就是IP的問題,換一批就好,因此我在下面的網站中找了一批又一批ip:
快代理、89免費代理、66免費代理、西刺代理
但是一直找不到能用的。。。

7.2.2 第二步嘗試:網上自動獲取可用id

轉自:https://www.jianshu.com/p/8449b9c397bb
自動把成功的id放到proxies.txt中,但是用了成功的id還是不行

# *-* coding:utf-8 *-* import requests from bs4 import BeautifulSoup import lxml from multiprocessing import Process, Queue import random import json import time import requestsclass Proxies(object):"""docstring for Proxies"""def __init__(self, page=3):self.proxies = []self.verify_pro = []self.page = pageself.headers = {'Accept': '*/*','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36','Accept-Encoding': 'gzip, deflate, sdch','Accept-Language': 'zh-CN,zh;q=0.8'}self.get_proxies()self.get_proxies_nn()def get_proxies(self):page = random.randint(1, 10)page_stop = page + self.pagewhile page < page_stop:url = 'http://www.xicidaili.com/nt/%d' % pagehtml = requests.get(url, headers=self.headers).contentsoup = BeautifulSoup(html, 'lxml')ip_list = soup.find(id='ip_list')for odd in ip_list.find_all(class_='odd'):protocol = odd.find_all('td')[5].get_text().lower() + '://'self.proxies.append(protocol + ':'.join([x.get_text() for x in odd.find_all('td')[1:3]]))page += 1def get_proxies_nn(self):page = random.randint(1, 10)page_stop = page + self.pagewhile page < page_stop:url = 'http://www.xicidaili.com/nn/%d' % pagehtml = requests.get(url, headers=self.headers).contentsoup = BeautifulSoup(html, 'lxml')ip_list = soup.find(id='ip_list')for odd in ip_list.find_all(class_='odd'):protocol = odd.find_all('td')[5].get_text().lower() + '://'self.proxies.append(protocol + ':'.join([x.get_text() for x in odd.find_all('td')[1:3]]))page += 1def verify_proxies(self):# 沒驗證的代理old_queue = Queue()# 驗證后的代理new_queue = Queue()print('verify proxy........')works = []for _ in range(15):works.append(Process(target=self.verify_one_proxy, args=(old_queue, new_queue)))for work in works:work.start()for proxy in self.proxies:old_queue.put(proxy)for work in works:old_queue.put(0)for work in works:work.join()self.proxies = []while 1:try:self.proxies.append(new_queue.get(timeout=1))except:breakprint('verify_proxies done!')def verify_one_proxy(self, old_queue, new_queue):while 1:proxy = old_queue.get()if proxy == 0: breakprotocol = 'https' if 'https' in proxy else 'http'proxies = {protocol: proxy}try:if requests.get('http://www.baidu.com', proxies=proxies, timeout=2).status_code == 200:print('success %s' % proxy)new_queue.put(proxy)except:print('fail %s' % proxy)if __name__ == '__main__':a = Proxies()a.verify_proxies()print(a.proxies)proxie = a.proxieswith open('proxies.txt', 'a') as f:for proxy in proxie:f.write(proxy+'\n')

7.2.3 最后懷疑是不是代碼問題,因此買了一批ip,發現可以使用,那么報錯就是一直沒有找到優質ip的原因,說明免費ip的網站質量真是很差。。。

7.3 建立ip池

傳送門

總結

以上是生活随笔為你收集整理的scrapy爬虫框架 (5. 避免被封措施)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。