爬蟲處理流程:
- 將互聯網上的網頁獲取到本地
- 對網頁進行解析
網頁解析是從網頁中分離出我們所需要的、有價值的信息,以及新的待爬取的URL。
網頁的解析的方法:- 正則表達式(采用模糊匹配的方式,找出我們所需要內容)
- BeautifulSoup(是一個可以從HTML或XML文件中提取數據的第三方Python庫), BeautifulSoup可以采用Python自帶的
html.parse
作為它的解析器,也可以采用lxml
作為解析器。
lxml 是Python語言解析處得XML和HTML的庫
- XPath(XPath 是一門在 XML 文檔中查找信息的語言,XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。)
- 對解析出來的數據進行處理。
一、使用BeautifulSoup
安裝:
pip install beautifulsoup4
安裝lxml:
pip install lxml
解析器 | 使用方法 | 優點 | 缺點 |
---|---|---|---|
Python標準庫 | BeautifulSoup(markup, “html.parser”) | Python的內置標準庫,執行速度適中,文檔容錯能力強 | Python 2.7.3 or 3.2.2)前 的版本中文檔容錯能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快,文檔容錯能力強 | 需要安裝C語言庫 |
- 首先必須要導入 bs4 庫,創建BeautifulSoup對象
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml') #html為下載的網頁,lxml為解析器
- 詳細使用可以看Beautiful Soup 4.2.0 文檔
掌握以下三個方法基本夠用:
- find_all("tag") 搜索當前所有的tag標簽的集合。
- find("tag") 返回的是一個tag標簽。(這個方法用得少)
- select("") 可以按標簽名查找,用得多的是按標簽逐層查找篩選元素。
二、使用BeautifulSoup提取網頁內容的一些技巧
1、find_all()方法中放單獨的標簽名,如a
,會提取網頁中所有的a
標簽,這里要確保是我們所需要的鏈接a
,一般都不是,需要加上條件(就是標簽的屬性,加以限制篩選),如果這一級標簽沒有屬性,最好往上一級找。
以糗事百科為例來說明,http://www.qiushibaike.com/text/
,抓取原創笑話段子。
發現內容都在span
標簽中,如果寫 find_all("span")
可以抓取到段子的內容,但是還包含了網頁上其他span
的內容。這時我們往上一級標簽上看,<div class="content>
就是只包含了段子內容的標簽。
# coding=utf-8
import requests
from bs4 import BeautifulSoup
html = requests.get('http://www.qiushibaike.com/text/').content
soup = BeautifulSoup(html,'lxml')
links = soup.find_all('div',class_='content')
for link in links:
print link.span.get_text()
取出來的link的內容就是div
,我們取它的span
中的內容就是我們需要段子的內容。
2、select() 方法,可以按標簽逐層查找到我們所需要的內容,這點特點方便,就是定位,避免了單一的標簽無法定位到我們所需要的內容元素。
soup.select("html head title") ##標簽層級查找
soup.select('td div a') ## 標簽路徑 td --> div --> a
soup.select('td > div > a')
注意,以上按路徑 標簽之間的空格 td div a,可以用>,但也要注意>與標簽之間都有空格。推薦使用 > 的方式。
我們使用Chrome瀏覽器,右鍵copy - selector (鼠標要放在標簽上)
注意得到的內容,是從
#
開始的,這是上面div
的id
(#
表示的是id
),如果按此去搜索標簽內容,只能得到一條內容。
#qiushi_tag_118962045 > a > div > span
需要改一下,按照個標簽順序去匹配搜索內容。這里第一個div
就是 有id數字的那個div
div > a > div > span
按這個路徑去搜索時,發現還匹配到評論的內容,這就是定位的問題,需要改得更準確一些。
a.contentHerf > div > span
改為從a
標簽開始,并且加上它的class
屬性。a.contentHerf
是<a class="contentHerf"
在select()方法中的寫法。
# coding=utf-8
import requests
from bs4 import BeautifulSoup
html = requests.get('http://www.qiushibaike.com/text/').content
soup = BeautifulSoup(html,'lxml')
links = soup.select('a.contentHerf > div > span')
for link in links:
print link.get_text()
#print link.text 這樣寫可以
兩種方式抓取到糗百的段子。注意這里只抓取了一頁的內容。
PS 可以參見之前的內容:使用Beautiful Soup抓取結構化數據