Python爬蟲解析網頁的三種方法,lxml、BeautifulSoup、re案例!
常用的類庫為lxml,BeautifulSoup,re(正則)
學習Python中有不明白推薦加入交流群
號:960410445
群裡有志同道合的小夥伴,互幫互助,
群裡有不錯的視訊學習教程和PDF!
以獲取豆瓣電影正在熱映的電影名為例,url='https://movie.douban.com/cinema/nowplaying/beijing/'
網頁分析
部分網頁原始碼
<ul class="lists"> <li id="3878007" class="list-item" data-title="海王" data-score="8.2" data-star="40" data-release="2018" data-duration="143分鐘" data-region="美國 澳大利亞" data-director="溫子仁" data-actors="傑森·莫瑪 / 艾梅柏·希爾德 / 威廉·達福" data-category="nowplaying" data-enough="True" data-showed="True" data-votecount="105013" data-subject="3878007" >
分析可知我們要的電影名稱資訊在li標籤的data-title屬性裡
下面開始寫程式碼
爬蟲原始碼展示
import requests from lxml import etree # 匯入庫 from bs4 import BeautifulSoup import re import time # 定義爬蟲類 class Spider(): def __init__(self): self.url = 'https://movie.douban.com/cinema/nowplaying/beijing/' self.headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' } r = requests.get(self.url,headers=self.headers) r.encoding = r.apparent_encoding self.html = r.text def lxml_find(self): '''用lxml解析''' start = time.time() # 三種方式速度對比 selector = etree.HTML(self.html) # 轉換為lxml解析的物件 titles = selector.xpath('//li[@class="list-item"]/@data-title') # 這裡返回的是一個列表 for each in titles: title = each.strip() # 去掉字元左右的空格 print(title) end = time.time() print('lxml耗時', end-start) def BeautifulSoup_find(self): '''用BeautifulSoup解析''' start = time.time() soup = BeautifulSoup(self.html, 'lxml') # 轉換為BeautifulSoup的解析物件()裡第二個引數為解析方式 titles = soup.find_all('li', class_='list-item') for each in titles: title = each['data-title'] print(title) end = time.time() print('BeautifulSoup耗時', end-start) def re_find(self): '''用re解析''' start = time.time() titles = re.findall('data-title="(.+)"',self.html) for each in titles: print(each) end = time.time() print('re耗時', end-start) if __name__ == '__main__': spider = Spider() spider.lxml_find() spider.BeautifulSoup_find() spider.re_find()
輸出結果
海王 無名之輩 無敵破壞王2:大鬧網際網路 狗十三 驚濤颶浪 毒液:致命守護者 憨豆特工3 神奇動物:格林德沃之罪.......................
程式碼說明
1. lxml
lxml是通過xpath來查詢
使用前需使用呼叫ertee.HTML()方法('()'內填HTML程式碼)生成一個可查詢的物件
常用xpath語法如下
//兩個斜槓為向下查詢孫子標籤
/一個斜槓為查詢直接兒子標籤
[]方括號內填標籤屬性,如查詢class屬性為name的a標籤,格式為a[@class="name"]
/text()取出標籤的內容,如查詢網頁中的 <a class="name">KAINHUCK</a> 中的KAINHUCK,格式為 //a[@class="name"]/text()
/@attr取出標籤的屬性,如查詢網頁中的 <a class="name">KAINHUCK</a> 中的class屬性值name,格式為 //a[@class="name"]/@class
2. BeautifulSoup
使用前需先將HTML轉換為課查詢物件,格式為
BeautifulSoup(html, 'lxml')
html 為HTML程式碼, 後面的引數為轉換方法(其他方法有 'html.parser' , 'html5lib' , 推薦使用 'lxml')
查詢方法
info = find('a', id='kain') 查詢第一個id屬性為kain的a標籤,並存進info變數中(其他標籤同理)
find_all('a', class_='name')查詢所有class屬性為name的a標籤(注: class 屬性需寫成 'class_')
info.p.text獲取第一個id屬性為kain的a標籤下的p標籤的內容(info為上面例子裡的info,其他同理)
info.p['name']獲取第一個id屬性為kain的a標籤下的p標籤的name屬性值(info為上面例子裡的info,其他同理)
當代碼中有很多同級標籤時
<p class='info-list'> <a class='name'>text1</a> <a class='name'>text2</a> <a class='name'>text3</a> <a class='name'>text4</a> </p>
示例程式碼如下
from bs4 import BeautifulSoup html = ''' <p class='info-list'> <a class='name'>text1</a> <a class='name'>text2</a> <a class='name'>text3</a> <a class='name'>text4</a> </p> ''' soup = BeautifulSoup(html, 'lxml') texts = soup.find('p', class_='info-list') print(texts.contents[1].text) # 輸出text1 print(texts.contents[2].text) # 輸出text2 print(texts.contents[3].text) # 輸出text3 print(texts.contents[4].text) # 輸出text4
注意:不是從0開始
3. re(正則表示式)
正則表示式內容較多,大家可以參考 這裡
總結
使用lxml查詢時可以在目標網頁按F12調出開發者視窗然後再在按Ctrl+f查詢,在查詢欄裡輸入你的xpath語法可以檢查是否能找到對應內容
可以從看例子的輸出中看出三種方法的速度
lxml耗時 0.007623910903930664 BeautifulSoup耗時 0.061043500900268555 re耗時 0.0004856586456298828
對以上三種最常用的解析網頁的方法做個對比
綜上,對於網頁內容的解析,這裡推薦新手使用lxml方法,而對速度有要求就使用正則表示式(入門有點困難)