第十六章 API例子:用Python驅動Firefox採集網頁數據

1,引言

本文講解怎樣用Python驅動Firefox瀏覽器寫一個簡易的網頁數據採集器。開源Python即時網路爬蟲項目將與Scrapy(基於twisted的非同步網路框架)集成,所以本例將使用Scrapy採集淘寶這種含有大量ajax代碼的網頁數據,但是要注意本例一個嚴重缺陷:用Selenium載入網頁的過程發生在Spider中,破壞了Scrapy的架構原則。所以,本例只是為了測試Firefox驅動和ajax網頁數據採集這兩個技術點,用於正式運行環境中必須予以修改,後續的文章將專門講解修正後的實現。

請注意,本例用到的xslt文件是通過MS謀數台保存提取器後,通過API介面獲得,一方面讓python代碼變得簡潔,另一方面,節省調試採集規則的時間。詳細操作請查看Python即時網路爬蟲:API說明 2,具體實現 2.1,環境準備

需要執行以下步驟,準備Python開發和運行環境:

  • 安裝Python--官網下載安裝並部署好環境變數 (本文使用Python版本為3.5.1)
  • 安裝lxml-- 官網庫下載對應版本的.whl文件,然後命令行界面執行 "pip install .whl文件路徑"
  • 安裝Scrapy--命令行界面執行 "pip install Scrapy",詳細請參考Scrapy:Python3下的第一次運行測試
  • 安裝selenium--命令行界面執行 "pip install selenium"
  • 安裝Firefox--官網下載安裝

上述步驟展示了兩種安裝:1,安裝下載到本地的wheel包;2,用Python安裝管理器執行遠程下載和安裝。

2,開發和測試過程

以下代碼默認都是在命令行界面執行

1),創建scrapy爬蟲項目simpleSpider

E:python-3.5.1>scrapy startproject simpleSpidern

2),修改settings.py配置

有些網站會在根目錄下放置一個名字為robots.txt的文件,裡面聲明了此網站希望爬蟲遵守的規範,Scrapy默認遵守這個文件制定的規範,即ROBOTSTXT_OBEY默認值為True。在這裡需要修改ROBOTSTXT_OBEY的值,找到E:python-3.5.1simpleSpidersimpleSpider下文件settings.py,更改ROBOTSTXT_OBEY的值為False。

3),導入API模塊

在項目目錄E:python-3.5.1simpleSpider下創建文件gooseeker.py(也可以在開源Python即時網路爬蟲GitHub源 的core文件夾中直接下載),代碼如下:

#!/usr/bin/pythonn# -*- coding: utf-8 -*-n# 模塊名: gooseekern# 類名: GsExtractorn# Version: 2.0n# 說明: html內容提取器n# 功能: 使用xslt作為模板,快速提取HTML DOM中的內容。n# released by 集搜客(http://www.gooseeker.com) on May 18, 2016n# github: https://github.com/FullerHua/jisou/core/gooseeker.pynnfrom urllib import requestnfrom urllib.parse import quotenfrom lxml import etreenimport timennclass GsExtractor(object):n def _init_(self):n self.xslt = ""n # 從文件讀取xsltn def setXsltFromFile(self , xsltFilePath):n file = open(xsltFilePath , r , encoding=UTF-8)n try:n self.xslt = file.read()n finally:n file.close()n # 從字元串獲得xsltn def setXsltFromMem(self , xsltStr):n self.xslt = xsltStrn # 通過GooSeeker API介面獲得xsltn def setXsltFromAPI(self , APIKey , theme, middle=None, bname=None):n apiurl = "http://www.gooseeker.com/api/getextractor?key="+ APIKey +"&theme="+quote(theme)n if (middle):n apiurl = apiurl + "&middle="+quote(middle)n if (bname):n apiurl = apiurl + "&bname="+quote(bname)n apiconn = request.urlopen(apiurl)n self.xslt = apiconn.read()n # 返回當前xsltn def getXslt(self):n return self.xsltn # 提取方法,入參是一個HTML DOM對象,返回是提取結果n def extract(self , html):n xslt_root = etree.XML(self.xslt)n transform = etree.XSLT(xslt_root)n result_tree = transform(html)n return result_treen

4),創建SimpleSpider爬蟲類

在項目目錄E:python-3.5.1simpleSpidersimpleSpiderspiders下創建文件simplespider.py,代碼如下:

# -*- coding: utf-8 -*-nimport timenimport scrapynfrom lxml import etreenfrom selenium import webdrivernfrom gooseeker import GsExtractornnclass SimpleSpider(scrapy.Spider):n name = "simplespider"n allowed_domains = ["taobao.com"]n start_urls = [n "https://item.taobao.com/item.htm?spm=a230r.1.14.197.e2vSMY&id=44543058134&ns=1&abbucket=10"n ]nn def __init__(self):n # use any browser you wishn self.browser = webdriver.Firefox()n n def getTime(self):n # 獲得當前時間戳n current_time = str(time.time())n m = current_time.find(.)n current_time = current_time[0:m]n return current_timen n def parse(self, response):n print("start...")n #start browsern self.browser.get(response.url)n #loading time intervaln time.sleep(3)n #get xsltn extra = GsExtractor()n extra.setXsltFromAPI("API KEY" , "淘寶天貓_商品詳情30474")n # get docn html = self.browser.execute_script("return document.documentElement.outerHTML");n doc = etree.HTML(html)n result = extra.extract(doc)n # out filen file_name = F:/temp/淘寶天貓_商品詳情30474_ + self.getTime() + .xmln open(file_name,"wb").write(result)n self.browser.close()n print("end") n

5),啟動爬蟲

在E:python-3.5.1simpleSpider項目目錄下執行命令

E:python-3.5.1simpleSpider>scrapy crawl simplespidern

6),輸出文件

採集到的網頁數據結果文件是:淘寶天貓_商品詳情30474_1466064544.xml

3,展望

調用Firefox,IE等全特性瀏覽器顯得有點太重量級,很多場合可以考慮輕量級的瀏覽器內核,比如,casperjs和phantomjs等。同時運行在沒有界面的瀏覽器(headless browser,無頭瀏覽器)模式下,也許可以對網頁數據採集性能有所提升。

然後,最重要的一點是要寫一個 Scrapy 的下載器,專門驅動這些瀏覽器採集網頁數據,也就是把這個功能從Spider中遷移出來,這樣才符合Scrapy的整體框架原則,實現事件驅動的工作模式。

4,相關文檔

1, Python即時網路爬蟲:API說明

2, API例子:用Java/JavaScript下載內容提取器

5,集搜客GooSeeker開源代碼下載源

1, GooSeeker開源Python網路爬蟲GitHub源

6,文檔修改歷史

1,2016-06-23:V1.0

2,2016-06-23:V1.1,在第一段明顯位置註明本案例的缺陷

上一章 Java/JavaScript的API例子 <<<<< 首頁 >>>>> 下一章 讓Scrapy的Spider更通用


推薦閱讀:

初學python--認識裝飾器
python的descriptor的意圖是什麼,想知道python當初弄出功能的意圖?困擾我好久了。
Python 的 Metaclass 有沒有什麼好的 Best Practice 可以學習?
拆代碼學演算法之用python實現KNN過程詳解

TAG:scrapy | 爬虫计算机网络 | Python |