大多數人利用lxml
和BeautifulSoup
這兩個包來提取資料。本文中我將不會介紹任何爬蟲框架的內容,因為我只利用最基礎的lxml
包來處理資料。也許你們會好奇為啥我更喜歡lxml
。那是因為lxml
利用元素遍歷法來處理資料而不是像BeautifulSoup
一樣利用正規表示式來提取資料。本文中我將介紹一個非常有趣的案例——之前我突然發現我的文章出現在最近的 Pycoders weekly issue 147中,因此我想爬取 Pycoders weekly 中所有檔案的連結。
很明顯,這是一個含有 JavaScript 渲染的網頁。我想要抓取網頁中所有的檔案資訊和相應的連結資訊。那麼我該怎麼處理呢?首先,我們利用 HTTP 方法無法獲得任何資訊。
1 2 3 4 5 6 7 8 |
import requests from lxml import html # storing response response = requests.get('http://pycoders.com/archive') # creating lxml tree from response body tree = html.fromstring(response.text) # Finding all anchor tags in response print tree.xpath('//div[@class="campaign"]/a/@href') |
當我們執行上述程式碼時,我們無法獲得任何資訊。這怎麼可能呢?網頁中明明顯示那麼多檔案的資訊。接下來我們需要考慮如何解決這個問題?
如何獲取內容資訊?
接下來我將介紹如何利用 Web kit 從 JS 渲染網頁中獲取資料。什麼是 Web kit呢?Web kit 可以實現瀏覽器所能處理的任何事情。對於某些瀏覽器來說,Web kit就是其底層的網頁渲染工具。Web kit 是QT
庫的一部分,因此如果你已經安裝QT
和PyQT4
庫,那麼你可以直接執行之。
你可以利用命令列來安裝該軟體庫:
1 |
sudo apt-get install python-qt4 |
現在所有的準備工作已經完成,接下來我們將使用一個全新的方法來提取資訊。
解決方案
我們首先通過 Web kit 傳送請求資訊,然後等待網頁被完全載入後將其賦值到某個變數中。接下來我們利用lxml
從 HTML 資料中提取出有效的資訊。這個過程需要一點時間,不過你會驚奇地發現整個網頁被完整地載入下來了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import sys from PyQt4.QtGui import * from PyQt4.Qtcore import * from PyQt4.QtWebKit import * class Render(QWebPage): def __init__(self, url): self.app = QApplication(sys.argv) QWebPage.__init__(self) self.loadFinished.connect(self._loadFinished) self.mainFrame().load(QUrl(url)) self.app.exec_() def _loadFinished(self, result): self.frame = self.mainFrame() self.app.quit() |
類Render
可以用來渲染網頁,當我們新建一個Render
類時,它可以將url
中的所有資訊載入下來並存到一個新的框架中。
1 2 3 4 5 |
url = 'http://pycoders.com/archive/' # This does the magic.Loads everything r = Render(url) # Result is a QString. result = r.frame.toHtml() |
利用以上的程式碼我們將 HTML 結果儲存到變數result
中,由於lxml
無法直接處理該特殊的字串資料,因此我們需要轉換資料格式。
1 2 3 4 5 6 7 |
# QString should be converted to string before processed by lxml formatted_result = str(result.toAscii()) # Next build lxml tree from formatted_result tree = html.fromstring(formatted_result) # Now using correct Xpath we are fetching URL of archives archive_links = tree.xpath('//div[@class="campaign"]/a/@href') print archive_links |
利用上述程式碼我們可以獲得所有的檔案連結資訊,接下來我們可以利用這些 Render
和這些URL連結來提取文字內容資訊。Web kit 提供了一個強大的網頁渲染工具,我們可以利用這個工具從 JS 渲染的網頁中抓取出有效的資訊。
總結
本文中我介紹了一個如何從 JS 渲染的網頁中抓取資訊的有效方法,這個工具雖然速度比較慢,但是卻非常簡單粗暴。我希望你會喜歡這篇文章。現在你可以將該方法運用到任何你覺得難以處理的網頁中。
祝一切順利。