Python網絡爬蟲

 引自:《手把手教你寫網絡爬蟲javascript

頁面數據提取

簡單的text文本提取

經過 F12, Ctrl+Shift+C 快捷鍵從網頁中直接抓取數據html

代碼以下:java

from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://jr.jd.com")
html_content = html.read()
html.close()  # 關閉url

# 利用bs4解析html文本
bsoup = BeautifulSoup(html_content, "html.parser")

# 解析所有class="nav-item-primary"的<a>標籤
bs_elem_set = bsoup.find_all("a", "nav-item-primary")  # <class 'bs4.element.ResultSet'>
for elem_tag in bs_elem_set:
    # print(type(elem_tag))  # <class 'bs4.element.Tag'>
    print("Debug::title_elem -->> ", elem_tag.get_text())

測試結果:python

動態網頁的數據提取

案例:咱們想從網易歌單 https://music.163.com/#/discover/playlist 中查詢播放次數超過500萬的所有歌單,查找關鍵字web

但事實上,經過 <span class="nb">29135</span> 咱們什麼也沒有提取到……瀏覽器

從網頁源碼中咱們能夠知道,該網頁經過javascript動態更新數據,咱們獲得的 nb=29135 數據行在 urlopen() 時還沒有被js代碼更新……網絡

用Python 解決這個問題只有兩種途徑:框架

  • 直接從 JavaScript 代碼裏採集內容;
  • 或者用 Python 的第三方庫運行 JavaScript,直接採集你在瀏覽器裏看到的頁面。

經過 Selenium 運行Js腳本,模擬瀏覽器載入動態網頁。代碼以下:less

from selenium import webdriver

browser = webdriver.PhantomJS()  # deprecated... replace by webdriver.Chrome() or Firefox()
browser.get("https://music.163.com/#/discover/playlist")

browser.switch_to.frame("contentFrame")
list_elems = browser.find_element_by_id("m-pl-container")\
                    .find_elements_by_tag_name("li")

for elem in list_elems:
    # print(type(elem))  # <class 'selenium.webdriver.remote.webelement.WebElement'>
    str_nb = elem.find_element_by_class_name("nb").text
    print(str_nb)  # I don't care the name, but just print the <nb>

browser.close()

首先須要 pip3 install selenium 模塊;加載動態網頁用的是 Headless 的 PhantomJS 瀏覽器,須要單獨安裝:choco install PhantomJS。curl

ps:最新版本的 selenium 棄用了 PhantomJS,呃...不過忽略那個報警,咱們這裏仍是能夠繼續執行的。

PySpider 應用

安裝 PySpider

經過 pip3 install pyspider 便可。過程當中遇到過如下問題,做以記錄:

Linux 沒法順利安裝,pip failed...

----------------------------------------
Cleaning up...
Command python setup.py egg_info failed with error code 1 in /tmp/pip-build-8q7t0vuz/pycurl
Storing debug log for failure in /root/.pip/pip.log

解決方案:既然 pip3 沒法成功安裝 pycurl,那就用其餘的方式:apt install python3-pycurl,而後再次 pip3 install pyspider,便可順利完成 PySpider 的安裝。

Windows 的問題不在安裝,而是啓動 pyspider 時報錯:

failed to create process.

經過 where pyspider,定位到程序位置:C:\Program Files\Python3\Scripts\pyspider.exe(因而可知,PySpider不能稱之爲框架,而是一個實在的爬蟲工具/程序),在同目錄下查詢到 pyspider-script.py 腳本,第一行是shebang:

#!c:\program files\python3\python.exe

改成:
#!"c:\program files\python3\python.exe"

這就解釋了爲何 Linux 環境能夠順利運行,而 Windows 則失敗了—— shebang不支持含有空格的路徑!

一方面,咱們得說是 PySpider 自動安裝腳本的bug,另外一方面,也的確是 Windows 系統的特殊性——路徑中容許空格能夠說是一個欠考慮的設計,至少在兼容性上它不夠完善。更嚴重的是,C:\Program Files\ 這個使用最頻繁的路徑,致使如今想要變動設計幾乎不可能了!這也提醒咱們,若是從新裝系統,把 Python/JVM 裝到其餘路徑下吧,例如 C:\usr\Python3\ (曾經我還想過,爲何Python在Windows上的安裝路徑默認會是C盤根目錄……)。

PySpider 的使用

具體步驟能夠參考:《Python爬蟲-pyspider框架的使用》https://www.jianshu.com/p/1f166f320c66

PySpider常見錯誤以及解決方案

整數錯誤

HTTP 599: SSL certificate problem: self signed certificate in certificate chain

這是由於https協議須要對證書進行驗證致使,解決方法是,在crawl()方法中使用validate_cert參數:

self.crawl(url, callback=self.last_page, validate_cert=False)

沒法使用全局變量傳遞參數值

crawl()方法中有專門的save參數解決變量傳遞的問題:

self.crawl(url, callback=self.last_page, save={'current_url': url, 'path': path_dir})

便可在目標函數中使用變量:response.save['current_url'] 和 response.save['path']

相關文章
相關標籤/搜索