Python分散式爬蟲詳解(一)
程序員大咖
點擊右側關注,免費進階高級!
作者:Zhiqi Kou
地址:zhihu.com/people/zhiqi-kou
當項目上升到一定境界時候,需要同時抓取幾百個甚至上千個網站,這個時候,單個的爬蟲已經滿足不了需求。比如我們日常用的百度,它每天都會爬取大量的網站,一台伺服器肯定是不夠用的。所以需要各個地方的伺服器一起協同工作。
本章知識點:
a.scrapy-redis簡介
b.開始項目前的準備
一、Scrapy-Redis 簡介
scrapy-redis是一個基於redis資料庫的scrapy組件,它提供了四種組件,通過它,可以快速實現簡單分散式爬蟲程序。
scrapy-redis組件 :
1、Scheduler(調度):Scrapy改造了python本來的collection.deque(雙向隊列)形成了自己Scrapy queue,而scrapy-redis 的解決是把這個Scrapy queue換成redis資料庫,從同一個redis-server存放要爬取的request,便能讓多個spider去同一個資料庫里讀取。Scheduler負責對新的request進行入列操作(加入Scrapy queue),取出下一個要爬取的request(從Scrapy queue中取出)等操作。
2、Duplication Filter(去重):Scrapy中用集合實現這個request去重功能,Scrapy中把已經發送的request指紋放入到一個集合中,把下一個request的指紋拿到集合中比對,如果該指紋存在於集合中,說明這個request發送過了,如果沒有則繼續操作。
3、Item Pipline(管道):引擎將(Spider返回的)爬取到的Item給Item Pipeline,scrapy-redis 的Item Pipeline將爬取到的 Item 存?redis的 items queue。
4、Base Spider(爬蟲):不再使用scrapy原有的Spider類,重寫的RedisSpider繼承了Spider和RedisMixin這兩個類,RedisMixin是用來從redis讀取url的類。
項目地址:
//github.com/rmax/scrapy-redishttps:
二、Scrapy-Redis 工作機制
1、首先Slaver端從Master端拿任務(Request、url)進行數據抓取,Slaver抓取數據的同時,產生新任務的Request便提交給 Master 處理;
2、Master端只有一個Redis資料庫,負責將未處理的Request去重和任務分配,將處理後的Request加入待爬隊列,並且存儲爬取的數據。
三、開始項目前的準備
1、Redis配置安裝:
工欲善其事必先利其器,既然是基於redis的服務,當然首先要安裝redis了。
安裝Redis伺服器端
install sudo apt-get
redis-
server
修改配置文件 redis.conf
sudo
將
bind 127.0.0.1
注釋掉。這樣Slave端才能遠程連接到Master端的Redis資料庫。
將Ubuntu作為Master端,Windows10和Windows7作為Slaver端,在Master中開啟redis-service服務。Slaver端也需要有redis。
serverredis-
Slaver連接測試:
redis-cli -h MasterIP地址
至此,redis已經安裝完成。
Redis可視化管理工具-Redis Desktop Manager
下載地址:
//redisdesktop.com/downloadhttps:
配置方法:
2、獲取自己的ip代理池
很多網站都有反爬蟲機制,只用一個ip去頻繁訪問網站的話,很容易引起網站管理員的注意,如果管理員將這個ip加入黑名單,那麼這個爬蟲就廢掉了。所以,想要做大型的爬蟲的話,基本上是必須要面對ip的問題。
那麼問題來了,我們去哪裡搞代理ip呢??第一種方法就是買買買!!沒有什麼事情是用錢解決不了的,如果有,那就加倍。
當然,網上也有一堆免費的ip代理,但是,免費的質量參差不齊,所以就需要進行篩選。以西刺代理為例:用爬蟲爬取國內的高匿代理IP,並進行驗證。(只爬取前五頁,後面的失效太多,沒有必要去驗證了。)
爬蟲:
class XiciSpider(scrapy.Spider)
name =
"xici"
allowed_domains = [
"xicidaili.com"
]start_urls = []
for
iin
range(1
,6
):start_urls.append(
"http://www.xicidaili.com/nn/"
+ str(i))
def
parse(self, response)
:ip = response.xpath(
"//tr[@class]/td[2]/text()"
).extract()port = response.xpath(
"//tr[@class]/td[3]/text()"
).extract()agreement_type = response.xpath(
"//tr[@class]/td[6]/text()"
).extract()proxies = zip(ip, port, agreement_type)
# print(proxies)
# 驗證代理是否可用
for
ip, port, agreement_typein
proxies:proxy = {
"http"
: agreement_type.lower() +"://"
+ ip +":"
+ port,"https"
: agreement_type.lower() +"://"
+ ip +":"
+ port}try
:# 設置代理鏈接 如果狀態碼為200 則表示該代理可以使用
print(proxy)
resp = requests.get(
"//icanhazip.com"
, proxies=proxy, timeout=2
)print(resp.status_code)
if
resp.status_code ==200
:print(resp.text)
# print("success %s" % ip)
item = DailiItem()
item[
"proxy"
] = proxyyield
itemexcept
:print(
"fail %s"
% ip)Pipeline:
class DailiPipeline object
def
__init__(
self
):self
.file = open("proxy.txt"
,"w"
)
def
process_item(
self
, item, spider):self
.file.write(str(item["proxy"
]) +"
"
return
item
def
close_spider(
self
, spider):self
.file.close()運行結果:
爬了500條數據,只有四條可以用………
本章項目地址:
//github.com/ZhiqiKou/Scrapy_noteshttps:
【點擊成為源碼大神】
※Python開發的十個Tips,你知道幾個?
※印度大學的學生如何練習編程
TAG:Python開發 |