scrapy爬蟲流程
阿新 • • 發佈:2017-10-27
scrapy 爬蟲學習
一、scrapy Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 其可以應用在數據挖掘,信息處 理或存儲歷史數據等一系列的程序中。其最初是為了頁面抓取 (更確切來說, 網絡抓取 )所設計的, 也 可以應用在獲取API所返回的數據(例如 Amazon Associates Web Services ) 或者通用的網絡爬蟲。 Scrapy用途廣泛,可以用於數據挖掘、監測和自動化測試。 Scrapy 使用了 Twisted異步網絡庫來處理網絡通訊。整體架構大致如下:
Scrapy主要包括了以下組件: 1.引擎(Scrapy) 用來處理整個系統的數據流處理, 觸發事務(框架核心) 2.調度器(Scheduler) 用來接受引擎發過來的請求, 壓入隊列中, 並在引擎再次請求的時候返回. 可以想像成一個URL(抓 取網頁的網址或者說是鏈接)的優先隊列, 由它來決定下一個要抓取的網址是什麽, 同時去除重復 的網址 3.下載器(Downloader) 用於下載網頁內容, 並將網頁內容返回給蜘蛛(Scrapy下載器是建立在twisted這個高效的異步模型 上的) 4.爬蟲(Spiders) 爬蟲是主要幹活的, 用於從特定的網頁中提取自己需要的信息, 即所謂的實體(Item)。用戶也可以 從中提取出鏈接,讓Scrapy繼續抓取下一個頁面 5.項目管道(Pipeline) 負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證實體的有效性、清除不需要的 信息。當頁面被爬蟲解析後,將被發送到項目管道,並經過幾個特定的次序處理數據 6.下載器中間件(Downloader Middlewares) 位於Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請求及響應 7.爬蟲中間件(Spider Middlewares) 介於Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應輸入和請求輸出 8.調度中間件(Scheduler Middewares) 介於Scrapy引擎和調度之間的中間件,從Scrapy引擎發送到調度的請求和響應 Scrapy運行流程大概如下: 1.引擎從調度器中取出一個鏈接(URL)用於接下來的抓取 2.引擎把URL封裝成一個請求(Request)傳給下載器 3.下載器把資源下載下來,並封裝成應答包(Response) 4.爬蟲解析Response 5.解析出實體(Item),則交給實體管道進行進一步的處理 6.解析出的是鏈接(URL),則把URL交給調度器等待抓取 二、安裝 1. linux #pip3 install scrapy 2.windows a. pip3 install wheel b. 下載twisted c. 進入下載目錄,執行 pip3 install Twisted17.1.0cp35cp35mwin_amd64.whl d. pip3 install scrapy e. 下載並安裝pywin32: 三、基本命令 1. scrapy startproject 項目名稱 - 在當前目錄中創建中創建一個項目文件(類似於Django) 2.scrapy genspider [-t template] <name> <domain> - 創建爬蟲應用 scrapy gensipider -t basic oldboy oldboy.com scrapy gensipider -t xmlfeed autohome autohome.com.cn 查看所有命令:scrapy gensipider -l 查看模板命令:scrapy gensipider -d 模板名稱 3. scrapy list - 展示爬蟲應用列表 4. scrapy crawl 爬蟲應用名稱 - 運行單獨爬蟲應用 5.項目結構以及爬蟲應用簡介 project_name/ scrapy.cfg project_name/ __init__.py items.py pipelines.py settings.py spiders/ __init__.py 爬蟲1.py 爬蟲2.py 爬蟲3.py 文件說明: scrapy.cfg 項目的主配置信息。(真正爬蟲相關的配置信息在settings.py文件中) items.py 設置數據存儲模板,用於結構化數據,如:Django的Model pipelines 數據處理行為,如:一般結構化的數據持久化 settings.py 配置文件,如:遞歸的層數、並發數,延遲下載等 spiders 爬蟲目錄,如:創建文件,編寫爬蟲規則 註意:一般創建爬蟲文件時,以網站域名命名 爬蟲文件oldboy.py例子: import scrapy class XiaoHuarSpider(scrapy.spiders.Spider): name = "xiaohuar" allowed_domains = ["xiaohuar.com"] start_urls = [ "http://www.xiaohuar.com/hua/", ] def parse(self,response): print(response.text) 註意windows編碼: import sys,os sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding=‘gb18030‘) 四、項目示例 import scrapy from scrapy.selector import HtmlXPathSelector from scrapy.http.request import Request class DigSpider(scrapy.Spider): name = "dig" allowed_domains = ["chouti.com"] start_urls = [ ‘http://dig.chouti.com‘, ] has_request_set = {} def parse(self, response): print(response.url) hxs = HtmlXPathSelector(response) page_list = hxs.select(‘//div[@id="dig_lcpage"]//a[re:test(@href, "/all/hot/recent/\d+")]/@href‘).extract() for page in page_list: page_url = ‘http://dig.chouti.com{0}‘.format(page) key = self.md5(page_url) if key in self.has_request_set: pass else: self.has_request_set[key] = page_url obj = Request(url=page_url, method=‘GET‘,callback=self.parse) yield obj @staticmethod def md5(val): import hashlib ha = hashlib.md5() ha.update(bytes(val, encoding=‘utf-8‘)) key = ha.hexdigest() return key 執行命令: scrapy crawl dig --nolog Request是一個封裝用戶請求的類,在回調函數中yield該對象表示繼續訪問 HtmlXpathSelector用於結構化HTML代碼並提供選擇器功能 登錄知乎: import scrapy from scrapy.selector import HtmlXPathSelector from scrapy.http.request import Request from scrapy.http.cookies import CookieJar from scrapy import FormRequest class ChouTiSpider(scrapy.Spider): # 爬蟲應用的名稱,通過此名稱啟動爬蟲命令 name = "chouti" # 允許的域名 allowed_domains = ["chouti.com"] cookie_dict = {} has_request_set = {} def start_requests(self): url = ‘http://dig.chouti.com/‘ # return [Request(url=url, callback=self.login)] yield Request(url=url, callback=self.login) def login(self, response): cookie_jar = CookieJar() cookie_jar.extract_cookies(response, response.request) for k, v in cookie_jar._cookies.items(): for i, j in v.items(): for m, n in j.items(): self.cookie_dict[m] = n.value req = Request( url=‘http://dig.chouti.com/login‘, method=‘POST‘, headers={‘Content-Type‘: ‘application/x-www-form-urlencoded; charset=UTF-8‘}, body=‘phone=xxxxxxxx&password=xxxxxx&oneMonth=1‘, cookies=self.cookie_dict, callback=self.check_login ) yield req def check_login(self, response): req = Request( url=‘http://dig.chouti.com/‘, method=‘GET‘, callback=self.show, cookies=self.cookie_dict, dont_filter=True ) yield req def show(self, response): # print(response) hxs = HtmlXPathSelector(response) news_list = hxs.select(‘//div[@id="content-list"]/div[@class="item"]‘) for new in news_list: # temp = new.xpath(‘div/div[@class="part2"]/@share-linkid‘).extract() link_id = new.xpath(‘*/div[@class="part2"]/@share-linkid‘).extract_first() yield Request( url=‘http://dig.chouti.com/link/vote?linksId=%s‘ %(link_id,), method=‘POST‘, cookies=self.cookie_dict, callback=self.do_favor ) page_list = hxs.select(‘//div[@id="dig_lcpage"]//a[re:test(@href, "/all/hot/recent/\d+")]/@href‘).extract() for page in page_list: page_url = ‘http://dig.chouti.com%s‘ % page import hashlib hash = hashlib.md5() hash.update(bytes(page_url,encoding=‘utf-8‘)) key = hash.hexdigest() if key in self.has_request_set: pass else: self.has_request_set[key] = page_url yield Request( url=page_url, method=‘GET‘, callback=self.show ) def do_favor(self, response): print(response.text) 註: settings.py中設置DEPTH_LIMIT = 1來指定“遞歸”的層數
本文出自 “linux技術” 博客,請務必保留此出處http://haoyonghui.blog.51cto.com/4278020/1976482
scrapy爬蟲流程