Python爬虫之解析网页
常用的類庫為lxml, BeautifulSoup, re(正則)
以獲取豆瓣電影正在熱映的電影名為例,url='https://movie.douban.com/cinema/nowplaying/beijing/'
網(wǎng)頁分析
部分網(wǎng)頁源碼
<ul class="lists"><liid="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="杰森·莫瑪 / 艾梅柏·希爾德 / 威廉·達(dá)福"data-category="nowplaying"data-enough="True"data-showed="True"data-votecount="105013"data-subject="3878007">分析可知我們要的電影名稱信息在li標(biāo)簽的data-title屬性里
下面開始寫代碼
爬蟲源碼展示
import requests from lxml import etree # 導(dǎo)入庫 from bs4 import BeautifulSoup import reimport 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_encodingself.html = r.textdef lxml_find(self):'''用lxml解析'''start = time.time() # 三種方式速度對(duì)比selector = etree.HTML(self.html) # 轉(zhuǎn)換為lxml解析的對(duì)象titles = selector.xpath('//li[@class="list-item"]/@data-title') # 這里返回的是一個(gè)列表for each in titles:title = each.strip() # 去掉字符左右的空格print(title)end = time.time()print('lxml耗時(shí)', end-start)def BeautifulSoup_find(self):'''用BeautifulSoup解析'''start = time.time()soup = BeautifulSoup(self.html, 'lxml') # 轉(zhuǎn)換為BeautifulSoup的解析對(duì)象()里第二個(gè)參數(shù)為解析方式titles = soup.find_all('li', class_='list-item')for each in titles:title = each['data-title']print(title)end = time.time()print('BeautifulSoup耗時(shí)', 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耗時(shí)', end-start)if __name__ == '__main__':spider = Spider()spider.lxml_find()spider.BeautifulSoup_find()spider.re_find()輸出結(jié)果
海王 無名之輩 無敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長嗎 云上日出 誰是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 lxml耗時(shí) 0.007623910903930664 海王 無名之輩 無敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長嗎 超時(shí)空大冒險(xiǎn) 天渠 愛不可及 二十歲 你好,之華 冒牌搭檔 鐵甲戰(zhàn)神 克隆人 恐怖快遞 中國藍(lán)盔 阿凡提之奇緣歷險(xiǎn) 名偵探柯南:零的執(zhí)行人 為邁克爾·杰克遜鑄造雕像 再見仍是朋友 心迷宮 淡藍(lán)琥珀 阿拉姜色 兩個(gè)俏公主 云上日出 誰是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 BeautifulSoup耗時(shí) 0.061043500900268555 海王 無名之輩 無敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長嗎 超時(shí)空大冒險(xiǎn) 天渠 愛不可及 二十歲 你好,之華 冒牌搭檔 鐵甲戰(zhàn)神 克隆人 恐怖快遞 中國藍(lán)盔 阿凡提之奇緣歷險(xiǎn) 名偵探柯南:零的執(zhí)行人 為邁克爾·杰克遜鑄造雕像 再見仍是朋友 心迷宮 淡藍(lán)琥珀 阿拉姜色 兩個(gè)俏公主 云上日出 誰是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 re耗時(shí) 0.0004856586456298828代碼說明
1. lxml
lxml是通過xpath來查找
使用前需使用調(diào)用ertee.HTML()方法('()'內(nèi)填HTML代碼)生成一個(gè)可查找的對(duì)象
常用xpath語法如下
// 兩個(gè)斜杠為向下查找孫子標(biāo)簽
/ 一個(gè)斜杠為查找直接兒子標(biāo)簽
[] 方括號(hào)內(nèi)填標(biāo)簽屬性,如查找class屬性為name的a標(biāo)簽,格式為a[@class="name"]
/text() 取出標(biāo)簽的內(nèi)容,如查找網(wǎng)頁中的 <a class="name">KAINHUCK</a> 中的KAINHUCK,格式為//a[@class="name"]/text()
/@attr 取出標(biāo)簽的屬性,如查找網(wǎng)頁中的 <a class="name">KAINHUCK</a> 中的class屬性值name,格式為//a[@class="name"]/@class
2. BeautifulSoup
使用前需先將HTML轉(zhuǎn)換為課查找對(duì)象,格式為
BeautifulSoup(html, 'lxml')
html 為HTML代碼, 后面的參數(shù)為轉(zhuǎn)換方法(其他方法有'html.parser' , 'html5lib', 推薦使用'lxml')
查找方法
info = find('a', id='kain') 查找第一個(gè)id屬性為kain的a標(biāo)簽,并存進(jìn)info變量中(其他標(biāo)簽同理)
find_all('a', class_='name') 查找所有class屬性為name的a標(biāo)簽(注:class屬性需寫成'class_')
info.p.text 獲取第一個(gè)id屬性為kain的a標(biāo)簽下的p標(biāo)簽的內(nèi)容(info為上面例子里的info,其他同理)
info.p['name'] 獲取第一個(gè)id屬性為kain的a標(biāo)簽下的p標(biāo)簽的name屬性值(info為上面例子里的info,其他同理)
當(dāng)代碼中有很多同級(jí)標(biāo)簽時(shí)
<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 BeautifulSouphtml = '''<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(正則表達(dá)式)
正則表達(dá)式內(nèi)容較多,大家可以參考這里
總結(jié)
使用lxml查找時(shí)可以在目標(biāo)網(wǎng)頁按F12調(diào)出開發(fā)者窗口然后再在按Ctrl+f查找,在查找欄里輸入你的xpath語法可以檢查是否能找到對(duì)應(yīng)內(nèi)容
可以從看例子的輸出中看出三種方法的速度
lxml耗時(shí) 0.007623910903930664
BeautifulSoup耗時(shí) 0.061043500900268555
re耗時(shí) 0.0004856586456298828
對(duì)以上三種最常用的解析網(wǎng)頁的方法做個(gè)對(duì)比
| 語法難易度 | 簡單 | 簡單 | 復(fù)雜 |
| 查找速度 | 較快 | 慢 | 快 |
綜上,對(duì)于網(wǎng)頁內(nèi)容的解析,這里推薦新手使用lxml方法,而對(duì)速度有要求就使用正則表達(dá)式(入門有點(diǎn)困難)
轉(zhuǎn)載于:https://www.cnblogs.com/kainhuck/p/10090448.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Python爬虫之解析网页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浦发VISA白金卡简约版年费是多少?如何
- 下一篇: Python自建collections模