在數(shù)據(jù)抓取的過程中,我們往往都需要對數(shù)據(jù)進行處理
本篇文章我們主要來介紹python的HTML和XML的分析庫BeautifulSoup
BeautifulSoup 的官方文檔網(wǎng)站如下
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
BeautifulSoup可以在HTML和XML的結(jié)構(gòu)化文檔中抽取出數(shù)據(jù)刃泌,而且還提供了各類方法,可以很方便的對文檔進行搜索署尤、抽取和修改耙替,能極大的提高我們數(shù)據(jù)挖掘的效率
下面我們來安裝BeautifulSoup
(上面我已經(jīng)安裝過了,所以沒有顯示進度條)
非常簡單曹体,無非就是pip install 加安裝的包名
pip3 install bs4
下面我們開始正式來學習這個模塊
首先還是提供一個目標網(wǎng)址
我的個人網(wǎng)站
下面我們通過requests的get方法保存這個網(wǎng)址內(nèi)容的源代碼
import requests
urls = "http://www.susmote.com"
resp = requests.get(urls)
resp.encoding = "utf8"
content = resp.text
with open("Bs4_test.html", 'w', encoding="utf8") as f:
f.write(content)
運行起來俗扇,我們馬上就能得到這個網(wǎng)頁的源代碼了
下面我們寫的程序就是專門針對這個源代碼利用BeautifulSoup來分析
首先我們來獲取里面所有的a標簽的href鏈接和對應(yīng)的文本
代碼如下
from bs4 import BeautifulSoup
with open("Bs4_test.html", 'r', encoding='utf8') as f:
bs = BeautifulSoup(f.read())
a_list = bs.find_all('a')
for a in a_list:
if a.text != "":
print(a.text.strip(), a["href"])
首先我們從BS4里面導入BeautifulSoup
然后以只讀模式打開文件打開文件,我們把f.read()作為BeautifulSoup的參數(shù)箕别,也就是將字符串初始化铜幽,把返回的對象記為bs
然后我們就可以調(diào)用BeautifulSoup的方法了,BeautifulSoup的最常用的方法就是find和find_all,可以在文檔中找到符合條件的元素串稀,區(qū)別就是找到一個除抛,和找到所有
在這里我們使用find_all方法,他的常用形式是
元素列表 = bs.find_all(元素名稱, attires = {屬性名:屬性值})
然后就是依次輸出找到的元素,這里就不多說 了
我們在命令行運行這段代碼
輸出結(jié)果如下
找尋的結(jié)果太多母截,不一一呈現(xiàn)
可以看到爬取的鏈接其中有很多規(guī)律
例如標簽鏈接
我們可以對代碼進行稍微的更改到忽,以獲取網(wǎng)站所有的標簽鏈接,也就是做一個過濾
代碼如下
from bs4 import BeautifulSoup
with open("Bs4_test.html", 'r', encoding='utf8') as f:
bs = BeautifulSoup(f.read(), "lxml")
a_list = bs.find_all('a')
for a in a_list:
if a.text != "" and 'tag' in a["href"]:
print(a.text.strip(), a["href"])
大致內(nèi)容沒有改變清寇,只是在輸出前加了一個判定條件喘漏,以實現(xiàn)過濾
我們在命令行運行這個程序
結(jié)果如下
除了這樣,你還可以使用很多方法達到相同的目標
使用attrs = [ 屬性名 : 屬性值 ] 參數(shù)
屬性名我相信學過html的人一定都知道华烟,例如"class"翩迈,"id"、"style"都是屬性盔夜,下面我們逐步深入负饲,利用這個來深入挖掘數(shù)據(jù)
獲取我的博客網(wǎng)站中每篇文章的標題
經(jīng)過瀏覽器調(diào)試堤魁,我們很容易獲取到我的博客網(wǎng)頁中標題部分的屬性樣式
如下圖
標題樣式是一個<header class="post-header">
非常簡單的一個屬性
下面我們通過代碼來實現(xiàn)批量獲取文章標題
# coding=utf-8
__Author__ = "susmote"
from bs4 import BeautifulSoup
n = 0
with open("Bs4_test.html", 'r', encoding='utf8') as f:
bs = BeautifulSoup(f.read(), "lxml")
header_list = bs.find_all('header', attrs={'class': 'post-header'})
for header in header_list:
n = int(n)
n += 1
if header.text != "":
print(str(n) + ": " + header.text.strip() + "\n")
大體上跟之前的代碼沒什么差別栈拖,只是在find_all方法中多加了一個參數(shù)辛藻,attrs以實現(xiàn)屬性過濾,然后為了使結(jié)果更清晰谦屑,我加了一個n
在命令行下運行,結(jié)果如下
利用正則表達式來表達屬性值的特征
無非就是在屬性值后面加一個正則匹配的方法吧慢,我在這就不過多解釋了涛漂,如果想要了解,可以自行上網(wǎng)百度
我的博客網(wǎng)站 www.susmote.com