利用python爬虫(part6)--用Xpath匹配带来的数据合并问题
學習筆記
如果在本Blog里看到拼音,那可能是由于第一次shen he沒通過被逼的,葛優(yōu)躺,不知所措。
用Xpath匹配帶來的數(shù)據(jù)合并問題
在我以往的爬蟲案例中(比如:X凰X聞案例),我用Xpath分別得到了Xin聞名稱列表name_list和Xin聞詳情鏈接列表link_list,并用zip()函數(shù),形成一個生成器對象,將兩個列表’合在一起’。
部分代碼如下(html源代碼就不貼在這里了,太占位置了):
parse_html = etree.HTML(html) link_xpath = \ '//ul[@class="news-stream-basic-news-list"]/li[@class="news-stream-newsStream-news-item-has-image clearfix news_item"]//h2/a/@href' name_xpath = \ '//ul[@class="news-stream-basic-news-list"]/li[@class="news-stream-newsStream-news-item-has-image clearfix news_item"]//h2/a/text()'link_list = parse_html.xpath(link_xpath) link_list = ['http:{}'.format(i) for i in link_list] name_list = parse_html.xpath(name_xpath) #只要使用xpath方法進行數(shù)據(jù)爬取,結果就會返回一個列表 data_zip = zip(name_list, link_list) for item in data_zip:print(item)這種方法看起來很方便,但是利用內置生成器函數(shù)zip(),會產(chǎn)生一些嚴重的問題,進而導致后續(xù)的數(shù)據(jù)分析錯誤。
- 舉個例子
有如下HTML代碼:
<ol><li class="Ra01"><name class = 'Bunny01'>小黃</name><age>8</age><food>胡蘿卜</food></li><li class="Ra01"><name class = 'Bunny02'>大白</name><age></age><food>白菜</food></li><li class="Ra02"><name class = 'Bunny03'>奧尼爾</name><age>20</age><food>提草</food></li><li class="Ra03"><name class = 'Bunny03'>王子</name><age>30</age><food>進口提草</food></li></ol>可以看到這個HTML頁面中有4對name和age數(shù)據(jù),但是由于某些不明原因,導致某些age節(jié)點中的數(shù)據(jù)丟失。
如果此時,我們要獲取HTML頁面中name節(jié)點和age節(jié)點中的文本中,則它們的Xpath可以寫成:
#name節(jié)點內文本 //ol/li/name/text() #age節(jié)點內文本 //ol/li/age/text()此時我們編寫python代碼:
# -*- coding: utf-8 -*-from lxml import etreehtml = \ """<ol><li class="Ra01"><name class = 'Bunny01'>小黃</name><age>8</age><food>胡蘿卜</food></li><li class="Ra01"><name class = 'Bunny02'>大白</name><age></age><food>白菜</food></li><li class="Ra02"><name class = 'Bunny03'>奧尼爾</name><age>20</age><food>提草</food></li><li class="Ra03"><name class = 'Bunny03'>王子</name><age>30</age><food>進口提草</food></li></ol> """parse_html = etree.HTML(html)#獲取所有name節(jié)點內文本 name_list = parse_html.xpath('//ol/li/name/text()') print(name_list) print('-'*20)#獲取所有age節(jié)點內文本 age_list = parse_html.xpath('//ol/li/age/text()') print(age_list)控制臺輸出:
['小黃', '大白', '奧尼爾', '王子'] -------------------- ['8', '20', '30']我們看到,由于HTML源代碼中某些age節(jié)點內的數(shù)據(jù)丟失,導致name_list和age_list的長度不一致,所以此時如果我們用內置生成器zip(),不僅會導致數(shù)據(jù)丟失,而且會導致name和age不匹配,這么說可能不夠形象,我們zip()一下,試試:
for item in zip(name_list, age_list):print(item)控制臺輸出:
('小黃', '8') ('大白', '20') ('奧尼爾', '30')我們看到,結果只輸出了3條數(shù)據(jù),且從’大白開始,各個name和age不匹配。
根據(jù)HTML源代碼,我們得到的數(shù)據(jù)應該是這樣的:
('小黃', '8') ('大白', '') ('奧尼爾', '20') ('王子', '30')所以,我們要換一種思維,用另一種方法,將數(shù)據(jù)’拼接’在一起。
比如:先獲取每一個li節(jié)點對象,將這些對象裝在一個列表中,再遍歷這個列表中的li節(jié)點對象,并分別對各個li節(jié)點對象獲取name和age文本數(shù)據(jù),并將它們拼接在一起。同樣,我們用代碼演示一遍:
parse_html = etree.HTML(html)#獲取所有l(wèi)i節(jié)點(大節(jié)點)對象 li_list = parse_html.xpath('//ol/li') #print(name_list) #print('-'*20)data_list = [] #遍歷li節(jié)點對象列表 for item in li_list:name = item.xpath('./name/text()')age = item.xpath('./age/text()')if not name:name = 'None'if not age:age = '0'data_list.append((name[0], age[0]))for item in data_list:print(item)注意,我們看到上面Xpath代碼./name/text()中,最開頭有一個.點,這個點有當前路徑的意思,換句話說,這個點代表了li節(jié)點所在的位置。
控制臺輸出:
('小黃', '8') ('大白', '0') ('奧尼爾', '20') ('王子', '30')可喜可賀!得到的name和age數(shù)據(jù)一個不少,且沒有出現(xiàn)name和age匹配錯誤的現(xiàn)象。
總結
以上是生活随笔為你收集整理的利用python爬虫(part6)--用Xpath匹配带来的数据合并问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flash如何制作可随意开动并能旋转的坦
- 下一篇: 索尼x1芯片重要吗(索尼在线商城)