摘要:微型異步爬蟲框架基于的異步框架,搭建一個模塊化的微型異步爬蟲。可以對該爬蟲的布隆過濾器進行配置,安裝中間件等。回調函數整個項目的主要實現在于回調函數的使用,利用異步請求得到響應后馬上調用其請求綁定的回調函數來實現爬蟲的異步爬取。
Amipy
Python微型異步爬蟲框架(A micro asynchronous Python website crawler framework)
基于Python 3.5 + 的異步async-await 框架,搭建一個模塊化的微型異步爬蟲。可以根據需求控制異步隊列的長度和延遲時間等。配置了可以去重的布隆過濾器,網頁內容正文過濾等,完全自主配置使用。
GitHub地址:源碼
適用環境windows 7 +
Python 3.5 +
安裝直接使用pip安裝即可:
pip install amipy基礎命令
1.查看當前路徑下的可用命令,在DOS命令行下輸入:
>amipy
會出現命令幫助界面。
2.創建一個新的項目,在DOS命令行下輸入:
>amipy cproject myproject
會在當前路徑下創建一個Amipy爬蟲項目myproject。如果想要創建在指定目錄下,可以加上附加參數,-d,如:
> amipy cproject myproject -d D:somefolder
項目myproject便會在路徑D:somefolder下創建。
項目的目錄結構應該如下:
--myproject |-spiders | |-__init__.py |-__init__.py |-settings.py
其中:
settings.py 為整個項目的配置文件,可以為整個項目下的爬蟲安裝共有的中間件,控制整個項目的請求并發數,設置日志級別、文件路徑等。
3.進入項目路徑,創建一個新的爬蟲,在DOS命令行下輸入:
>amipy cspider myspider
此時在項目myproject目錄下的spiders文件夾中會創建一個爬蟲目錄myspider,此時的項目結構為:
--myproject |-spiders | |-__init__.py | |-myspider | | |-__init__.py | | |-cookies.info | | |-item.py | | |-settings.py | | |-site_record.info | | |-spider.py | | |-url_record.info |-__init__.py |-settings.py |-log.log
其中:
位于myspider文件夾下的settings.py為爬蟲myspider的配置文件,該配置只對當前爬蟲有效。可以對該爬蟲的布隆過濾器進行配置,安裝中間件等。
cookies.info 為爬蟲的請求cookie保存文件,該爬蟲爬過的所有網站的cookie會保存進該文件。可以通過爬蟲配置文件settings.py進行路徑加載和保存。
site_record.info 為爬蟲爬取過的網站的布隆過濾器記錄文件,方便下次爬取的時候加載,會把爬取過的網站自動去掉。防止重復爬取。
url_record.info 為該爬蟲發出的請求url+headers+method+數據的去重后集合,爬蟲結束運行時,如果配置保存去重url集合。下次爬取時加載該文件可以自動過濾爬取過的所有url+headers+method+數據。
item.py 為ORM的MongoDB數據集合對象,對應的類屬性可以映射到數據庫集合中的字段,類名為數據表名。
spider.py 為當前爬蟲的主要文件,自己編寫爬取邏輯,提取規則和數據保存腳本等。
4.運行項目下的所有爬蟲,進入項目路徑,在DOS命令行下輸入:
>amipy runproject
則該項目下的所有爬蟲會開始運行,如果不想運行某個爬蟲,只需要加上參數 -e,如:
>amipy runproject -e No1spider No2spider
則名為“No1spider”、“No2spider”的爬蟲均不會運行。
5.運行指定的爬蟲,進入項目路徑,在DOS命令行下輸入:
>amipy runspider myspider01
則名為“myspider01”的爬蟲便會被啟動。可以加上多個爬蟲名稱,用空格隔開即可。
6.列出當前項目下的所有爬蟲信息。在DOS命令行下輸入:
>amipy list
便會將當前項目下的所有爬蟲信息列出。
使用 Amipy爬蟲編寫流程編寫自己的爬蟲。【假設你已經安裝前面"基礎命令"創建了一個項目,并且創建了一個爬蟲名為myspider】只需要進入myspider文件夾,按照需求修改當前爬蟲的配置settings.py 以及數據存儲需要用到的表模型item.py編寫,編輯文件spider.py,加入爬取規則邏輯等。
Url類對象Url類對象是一個規則匹配類,它提供了許多種模式的url規則匹配。
比如:
from amipy import Url # 表示匹配到正則模式"http://www.170mv.com/song.*"的所有鏈接 Url(re="http://www.170mv.com/song.*") # 表示匹配到正則模式"http://www.170mv.com/song.*"的所有鏈接其回調函數為"getmp3" Url(re="http://www.170mv.com/song/.*",callback="getmp3") # 表示匹配到地址為http協議,且路徑為‘/novel/chapter1’,參數number=2的所有鏈接 Url(scheme="http",path="/novel/chapter1",params="number=2") # 表示匹配到域名為www.baidu.com的所有鏈接,為該鏈接請求設置代理為"127.0.0.1:1080" Url(domain="www.baidu.com",proxy="127.0.0.1:1080") # 表示匹配到域名為www.baidu.com的所有鏈接,直接扔掉這些鏈接。 Url(domain="www.baidu.com",drop=True)
Url類應用的還在于黑白名單屬性中,如在爬蟲類中的屬性:
whitelist = [ Url(re="http://www.170mv.com/song.*"), Url(re="http.*.sycdn.kuwo.cn.*"),] blacklist = [ Url(re="http://www.170mv.com/song.*"), Url(re="http.*.sycdn.kuwo.cn.*"),]
表示爬蟲請求的url黑白名單匹配規則。
必要屬性打開spider.py ,可以看到有兩個默認的必要屬性:
name 爬蟲的唯一標識,項目下不能有該屬性重名的爬蟲。
urls 起始鏈接種子,爬蟲開始的url列表
這兩個屬性是必須的。
回調函數整個項目的主要實現在于回調函數的使用,利用異步請求得到響應后馬上調用其請求綁定的回調函數來實現爬蟲的異步爬取。
請求后響應的回調函數(類方法)有:
parse 返回狀態200,請求正常響應正常,可以編寫正常的規則提取、數據保存等。
error 狀態碼非200,出現異常狀態碼,編寫錯誤處理邏輯等。
exception 請求出現異常,異常自定義處理。
數據存儲Amipy目前只支持MongoDB數據庫,默認的數據庫設置在爬蟲配置文件settings.py中。
對于爬取的數據進行保存,默認只使用MongoDB進行數據存儲(后續可以自己擴展編寫ORM)。只需要打開item.py,修改其中的示例類,原先為:
from amipy.BaseClass.orm import Model,Field class DataItemName(Model): ...
修改其內容為:
from amipy.BaseClass.orm import Model,Field class MyTableName(Model): ID = Field("索引") content = Field("內容")
則類名 MyTableName為保存在指定數據庫中的數據集合名稱,ID為列對象,名稱為“索引”,以此類推,content也為列對象,名稱為“內容”。
可以按照自己的需求進行添加刪減列。
數據的保存只需要在回調函數中對對應的列對象進行賦值,而后調用ORM對象的save函數即可。比如在spider.py的爬蟲類中的成功回調函數parse中保存爬取到的數據:
... def parse(self,response): self.item.ID = 200 self.item.content = "這是內容" self.item.save() ...
則 數據集合 MyTableName中會自動保存一行數據:列“索引”為200,列“內容”為“這是內容”的數據行。引用orm數據模型對象只需要調用爬蟲類的item屬性,如上面示例中的self.item即是。
獲取其數據庫對象可以使用:self.item.db來獲得當前爬蟲連接的MongoDB數據庫對象。
可以通過
self.item.db.save() self.item.db.delete() self.item.db.update() ...
等api來實現數據庫操作。
事件循環loopAmipy爬蟲的異步請求基于python3的協程async框架,所以項目全程只有一個事件循環運行,如果需要添加更多的爬蟲請求,可以通過回調函數傳進事件循環,加入請求隊列。
具體做法便是通過在爬蟲類的回調函數中使用send函數來傳遞請求Request對象:
import amipy from amipy import Request,send class MySpider(amipy.Spider): ... def parse(self,response): ... # 加入新的爬蟲請求 url = "http://www.170mv.com/download/" send(Request(self,url)) ...
可以在項目配置文件settings.py中設置整個項目最大的協程并發數CONCURRENCY,以及協程請求的延時等。
Telnet連接Amipy爬蟲內置一個服務線程,可以通過Telnet進行連接來查看操作當前項目的爬蟲,在啟動爬蟲后,可以通過新開一個DOS命令窗口,
輸入:
>telnet 127.0.0.1 2232
進行Telnet連接至項目服務線程,可以使用的命令有:
show spiders show all running spiders and their conditions. list list a general situation of all spiders. echo echo a running spider and its attributes. pause pause a running spider by a give name. stop stop a running/paused spider by a give name. close close a spider by a give name. restart restart a stopped spider by a give name. resume resume a paused spider by a give name. quit quit the Spider-Client. help show all the available commands usage.
舉例,假設當前爬蟲唯一標識名稱為lianjia,則可以通過:
$amipy> pause lianjia
來暫停爬蟲lianjia的爬取進度,在爬蟲將當前請求隊列清空后會一直暫停,直到收到Telnet端發出的其他命令。恢復爬蟲使用:
$amipy> resume lianjia
查看當前項目下所有爬蟲:
$amipy> list
詳細查看則使用:
$amipy> show spiders
開啟關閉Telnet在項目的配置文件settings.py中設置SPIDER_SERVER_ENABLE。
爬取去重Amipy的爬取去重可以分為兩種:
url去重
網頁內容正文去重
兩者皆使用了布隆過濾器去重,對于url去重,則是使用url+method+params+data的方式生成摘要進行布隆過濾器去重。
對于網頁正文去重則是按照配置文件指定的正文檢測參數來檢測每個網頁的正文內容生成摘要存進布隆過濾器,可以在爬蟲的配置文件
settings.py中對以下幾項進行配置來檢測網頁內容正文:
# 網頁內容剔除掉哪些標簽后再識別正文 BLOOMFILTER_HTML_EXTRACTS = ["script","style","head"] # 允許一個正文內容塊中至多空行數 BLOOMFILTER_HTML_GAP = 3 # 連續多少行有正文則認為是一個正文塊 BLOOMFILTER_HTML_THRESHOLD = 5 # 每一行正文的字密度 BLOOMFILTER_HTML_DENSITY =45
上面兩種是默認的去重方式,還可以指定請求返回的網頁內容的某一部分作為響應指紋來進行針對性的去重。
如果想要自己指定哪個響應內容部分作為去重的指紋,可以在將請求Request送進協程隊列時指定指紋函數,如:
... def parse(self,response): ... send(Request(self,url,fingerprint=self.fingerprint)) ... def fingerprint(self,response): ... # 返回需要作為指紋的文本字符等 return something例子 1. 使用Amipy創建鏈家網爬蟲(LianJiaSpider)
爬蟲目的:爬取鏈家網上北京當前最新的租房信息,包含“價格”,“房屋基本信息”、“配套設施”、“房源描述”、“聯系經紀人”、“地址和交通”存入MongoDB數據庫中
創建項目
進入到D:LianJia路徑,創建Amipy項目LJproject:
D:LianJia> amipy cproject LJproject
創建爬蟲
進入到項目路徑D:LianJiaLJproject,創建Amipy爬蟲lianjia:
D:LianJiaLJproject> amipy cspider lianjia
編寫數據庫模型
打開D:LianJiaLJprojectspidersLianjiaitem.py,編寫數據保存模型:
#coding:utf-8 from amipy.BaseClass.orm import Model,Field class LianJiaRenting(Model): price = Field("價格") infos = Field("房屋基本信息") facility = Field("配套設施") desc = Field("房源描述") agent = Field("聯系經紀人") addr = Field("地址與交通")
設置數據庫連接
打開 D:LianJiaLJprojectspidersLianjiasettings.py,找到MongoDB數據庫連接設置,進行設置:
# MongoDB settings for data saving. DATABASE_SETTINGS = { "host":"127.0.0.1", "port":27017, "user":"", "password":"", "database":"LianJiaDB", }
要先確保系統安裝好MongoDB數據庫并已經開啟了服務。
編寫爬蟲腳本
打開 D:LianJiaLJprojectspidersLianjiaspider.py,編寫爬蟲采集腳本:
import amipy,re from amipy import send,Request,Url from bs4 import BeautifulSoup as bs class LianjiaSpider(amipy.Spider): name = "lianjia" # 設置爬取初始鏈接 urls = ["https://bj.lianjia.com/zufang/"] # 設置爬蟲白名單,只允許爬取匹配的鏈接 whitelist = [ Url(re="https://bj.lianjia.com/zufang/.*"), ] # 自定義的屬性 host ="https://bj.lianjia.com" page = 1 # 請求成功回調函數 def parse(self,response): soup = bs(response.text(),"lxml") item_list = soup("div",class_="content__list--item") for i in item_list: # 獲取詳情頁鏈接 并發送至爬蟲請求隊列 url = self.host+i.a["href"] send(Request(self,url,callback=self.details)) # 添加下一頁 totalpage = soup("div",class_="content__pg")[0]["data-totalpage"] if self.page>=int(totalpage): return self.page +=1 send(Request(self,self.host+"/zufang/pg{}/".format(self.page))) def details(self,response): infos = {} agent = {} facility = [] soup = bs(response.text(),"lxml") infos_li = soup("div",class_="content__article__info")[0].ul("li") facility_li = soup("ul",class_="content__article__info2")[0]("li") agent_ul = soup("ul",id="agentList")[0] addr_li = soup("div",id="around")[0].ul.li desc_li = soup("div",id="desc")[0].li desc_li.div.extract() desc = desc_li.p["data-desc"] if desc_li.p else "" for i in infos_li: text = i.text if ":" in text: infos.update({text.split(":")[0]:text.split(":")[1]}) for i in facility_li[1:]: if "_no" not in i["class"][-2]: facility.append(i.text) for div in agent_ul("div",class_="desc"): name = div.a.text phone = div("div",class_="phone")[0].text agent[name]=phone # 數據模型對應并保存 self.item.desc = desc self.item.addr = re.sub(r"[ ]","",addr_li.text) if addr_li else "" self.item.price = soup("p",class_="content__aside--title")[0].text self.item.infos = infos self.item.agent = agent self.item.facility = facility self.item.save()
如果在爬蟲配置文件settings.py中設置遵守目標網站機器人協議可能會被禁止采集,可以自行關閉設置。
另外,開啟網頁內容相似過濾BLOOMFILTER_HTML_ON可能會使爬取的結果數較少,爬蟲只會采集相似度不同的網頁內容的鏈接,
如果需要大批量采集,而網頁正文較少的,可以關閉這個設置。
代碼比較粗糙,但可以知道Amipy爬蟲基本的實現流程。
運行爬蟲
在項目根路徑下,輸入:
D:LianJiaLJproject> amipy runspider
查看數據庫
進入MongoDB數據庫:可以看到在數據庫‘LianJiaDB’下的集合“LianJiaRenting”中已經保存有我們爬取的數據,格式如下:
{ "_id" : ObjectId("5c6541b065b2fd1cf002c565"), "價格" : "7500元/月 (季付價)", "房屋基本信息" : { "發布" : "20天前", "入住" : "隨時入住", "租期" : "2~3年", "看房" : "暫無數據", "樓層" : "中樓層/6層", "電梯" : "無", "車位" : "暫無數據", "用水" : "民水", "用電" : "民電", "燃氣" : "有", "采暖" : "集中供暖" }, "配套設施" : [ "電視", "冰箱", "洗衣機", "空調", "熱水器", "床", "暖氣", "寬帶", "衣柜", "天然氣" ], "房源描述" : "【交通出行】 小區門口為八里莊南里公交車站,75,675等多路公交經過。地鐵6號線十里堡站D口,距離地鐵口400米,交通十分方便,便于出行。
【周邊配套】 此房位置棒棒噠,有建設銀行,中國銀行,交通銀行,郵政儲蓄,果多美水果超市,購物,金旭菜市場,娛樂,休閑,便利。旁邊首航超市,姥姥家春餅,味多美蛋糕店,生活方便。
【小區介紹】 該小區中此樓是1981建成,安全舒適,小區內主力樓盤為6層板樓,前后無遮擋,此樓是多見的板樓,樓層高視野好。
", "聯系經紀人" : { "宋玉恒" : "4000124028轉7907" }, "地址與交通" : "距離6號線-十里堡192m" }
查看當前爬取進度
新開一個DOS端口,輸入:
> telnet 127.0.0.1 2232
進行Telnet連接,可以使用命令操作查看當前爬蟲的爬取狀態。例如使用echo命令:
$amipy> echo lianjia
可以查看當前爬蟲的狀態:
----------------Spider-lianjia------------------- - Name:lianjia Status:RUNNING - Class:LianjiaSpider - Success:25 Fail:0 Exception:0 - Priority:0 - SeedUrls:["https://bj.lianjia.com/zufang/"] - Path:D:LianJiaLJprojectspidersLianjia - Session:- StartAt:Thu Feb 14 20:30:21 2019 - PausedAt:None - ResumeAt:None - StopAt:None - RestartAt:None - CloseAt:None --------------------------------------------------
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43176.html
摘要:輕量級框架是一個輕量級框架,包含多維數據分析和瀏覽聚合數據等工具。創造矢量地圖的輕量級框架是一個庫,用來為生成地圖。異步非阻塞的框架的全稱是,傳說中性能高高的框架。 如果你正在學習python,那么這10個開源框架,你可千萬別錯過,這些框架包括事件I/O,OLAP,Web開發,高性能網絡通信,測試,爬蟲等。雖說不上是全都有,但也足夠滿足你了。 1.Django: Python Web應...
摘要:當使用到后者這類微型框架時,根據業務場景不同,如果需要處理模型的建立升級和遷移的問題,可以考慮下接下來要介紹的和。這時候檢查數據庫,可以發現生成了張表,升級工作就完成了。而我在使用的實際項目中是操作的原生,異步類型的配合使用留待以后探究。 背景 Python的世界里有許多web框架:比如大而全的 Django, 提供了模型定義遷移,到路由處理,再到視圖的渲染等整套功能;比如小巧靈活的F...
摘要:輕量異步爬蟲框架,基于,目的是讓編寫單頁面爬蟲更方便更迅速,利用異步特性讓爬蟲更快減少在上的耗時介紹對于單頁面,只要實現框架定義的就可以實現對目標數據的抓取對于頁面目標較多,需要進行深度抓取時,就派上用場了支持的加載類也可以很好的 aspider A web scraping micro-framework based on asyncio. 輕量異步爬蟲框架aspider,基于asy...
摘要:在這之前,還是有必要對一些概念超輕量級反爬蟲方案后端掘金前言爬蟲和反爬蟲日益成為每家公司的標配系統。 爬蟲修煉之道——從網頁中提取結構化數據并保存(以爬取糗百文本板塊所有糗事為例) - 后端 - 掘金歡迎大家關注我的專題:爬蟲修煉之道 上篇 爬蟲修煉之道——編寫一個爬取多頁面的網絡爬蟲主要講解了如何使用python編寫一個可以下載多頁面的爬蟲,如何將相對URL轉為絕對URL,如何限速,...
閱讀 3674·2021-11-16 11:41
閱讀 2879·2021-09-23 11:45
閱讀 686·2019-08-30 15:44
閱讀 538·2019-08-30 13:10
閱讀 1960·2019-08-30 12:49
閱讀 3525·2019-08-28 17:51
閱讀 1470·2019-08-26 12:20
閱讀 697·2019-08-23 17:56