上一篇文章爬取動(dòng)態(tài)網(wǎng)頁python+selenium+webdriver介紹了爬取動(dòng)態(tài)網(wǎng)站的一種模擬瀏覽器的方法,該方法的優(yōu)劣也很明顯
優(yōu):
可以模擬任何人的操作,輸入賬號(hào)密碼,點(diǎn)擊登錄等等操作
劣:
1.每次執(zhí)行都要打開桌面上的Chrome瀏覽器(自動(dòng)化測(cè)試需要)
2.瀏覽器的各個(gè)操作步驟都需要sleep幾秒進(jìn)行等待,效率低
本文針對(duì)兩個(gè)劣點(diǎn)的進(jìn)行解決
PhantomJS
webdriver有很多種類的瀏覽器比如Internet Explorer、Chrome和 Firefox等,PhantomJS是一個(gè)無界面的瀏覽器,可以解決第一個(gè)問題。
渲染的問題
一個(gè)含有 JS 渲染的網(wǎng)頁。想要抓取網(wǎng)頁中所有信息。如果我們利用 HTTP 方法無法獲得任何信息。
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')
因?yàn)檫@是動(dòng)態(tài)渲染的網(wǎng)站,我們只能拿到一堆還沒被解析為html的js代碼。
Web kit
什么是 Web kit呢?
Web kit 可以實(shí)現(xiàn)瀏覽器所能處理的任何事情。對(duì)于某些瀏覽器來說,Web kit就是其底層的網(wǎng)頁渲染工具。
Web kit 是 QT 庫的一部分,因此需要安裝 QT 和PyQT4 庫來使用Web kit
sudo apt-get install python-qt4
注意:
上篇文章中使用selenium+webdriver其實(shí)也是通過瀏覽器來進(jìn)行渲染那些js,原理相同
解析數(shù)據(jù)
思路:我們首先通過 Web kit 發(fā)送請(qǐng)求信息,然后等待網(wǎng)頁被完全加載后將其賦值到某個(gè)變量中。接下來我們利用 lxml 從 HTML 數(shù)據(jù)中提取出有效的信息。
1.類 Render 可以用來渲染網(wǎng)頁,當(dāng)我們新建一個(gè) Render 類時(shí),它可以將 url 中的所有信息加載下來并存到一個(gè)新的框架中。
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()
2.利用以上的代碼我們將 HTML 結(jié)果儲(chǔ)存到變量 result 中
url = 'http://pycoders.com/archive/'
# This does the magic.Loads everything
r = Render(url)
# Result is a QString.
result = r.frame.toHtml()
3.轉(zhuǎn)換數(shù)據(jù)格式并解析
# 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
總結(jié)
1.動(dòng)態(tài)網(wǎng)站爬取核心步驟是渲染js
2.python+selenium+webdriver方式是模擬出真實(shí)環(huán)境解決的,既可以解決渲染,又可以附帶很多人的操作(輸入、點(diǎn)擊、最大化等),功能強(qiáng)大但是純采集的話效率略低
3.python+Web kit方式直接把渲染的核心部件拿出來進(jìn)行解決,這種方式簡單直接,作為純采集來說是首選,但是受限于需要登錄驗(yàn)證的網(wǎng)站