python3 爬蟲面對如此多重複的標籤,應該怎麼爬才能爬到自己需要的資訊
我們知道 利用BeautifulSoup解析網頁可以根據樹以及各個標籤來爬去 ,但是有個問題我們不能忽略,比如
1 BeautifulSoup
只要目標資訊的旁邊或者附近有標籤就可以呼叫 ,,不用管是幾層標籤(父輩 後代輩 的都可以)。
Soup.html.body.h1
Soup.body.h1
Soup.html.h1
Soup.h1
從上述可以看出來 我們存在以下疑問:
1為什麼一個標籤會有這麼多表示的形式,有啥用?
2一個網頁可能有很多相同的標籤(如網頁 d標籤可能存在10個以上),那我們怎麼能定位到自己想要的標籤中?
想想這些問題確實棘手,但是如果認真品讀的話,你會發現這兩個問題相輔相成,可以互為答案。兩個問題,結合再一起,可以解決彼此的問題了
我們再遍歷標籤時,需要提取自己需要的關鍵資訊,並且需要用獨一無二的方式表達出該標籤與其他同類標籤不同,那麼問題就迎刃而解了。
多說無益 我們來個幾個例子。
例子1:
我們來看下經典案例 中國最好大學排名。
我們要爬去 大學名字 tbody→tr→ td (找到tbody也挺重要的 因為可能文章中出現多個tr,如果沒有tbody限制,可能爬去的內容會過多,或者出現爬去不到的結果)。
我們這裡根據上面的方法可以有兩種方案 一種是直接爬去(更直觀,但是需要自己分出每個標籤的關係):
這裡我們注意到 奇數和偶數不一樣 奇數項多了個tr的class 而偶數則沒有 所有不能通過這個class來提取tr
方案一:
a=soup.find("tbody").findAll("tr") for i in a: tds = i("td")#不能用tr.attrs["td"] 因為這是個列表了 而不是BeatutifulSoup型別的資料了 ulist.append([tds[0].string])
即先找到tbody標籤 然後再爬去tbody下的標籤tr有了限制,然後再把tr標籤下的td標籤的string爬去出來就可以了。此方法一目瞭然,但是需要自行分析。
方案二:
soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string])
這個方法就是直接在tbody中提取標籤tr 加了一個判斷 如果是標籤再執行,如果不是我們就不用過問
這樣的好處就是可以很快的提取我們想要的標籤,並且淘汰掉我們不用的標籤。
例子2
例如這個例子中,我們可以觀察到,我們要按順序爬去每一章節的小說,div→o1→li→a 如果按這個順序可以。但是我們執行完畢才會發現
爬去的是993-1008章節的資料。 為什麼呢 我們返回來看一下小說原來的目錄
原來他吧最新更新都放在了前面了
方案一
我們要按順序爬去只能爬第二個div
soup = BeautifulSoup(r.content, "lxml") soup_texts = soup.find("ol", {"class":"clearfix"}).find_next("div") for link in soup_texts.findAll("li"): # if link != '\n':#濾除回車 print(link.a.string +":",link.a.attrs['href'])
這裡先找到01這個標籤 然後把包含01這個標籤的div找到 ,並且是找到第二個
意思就是 找到第二個div標籤下的01標籤 命名為soup_texts
然後遍歷01這個標籤 找到所有的li標籤 輸出a標籤下的string和href
然後就可以吧章節和章節連線找到了。
方案二
soup = BeautifulSoup(html, 'lxml') soup_texts = soup.find('div', id = 'book_detail', class_= 'box1').find_next('div') for link in soup_texts.ol.children: if link != '\n': print(link.text + ': ', link.a.get('href'))
直接找div標籤 然後在找第二個標籤
找到div標籤之後 遍歷所有的孩子標籤,組成了一個set集合 說明children是一個集合 並不是beautifulSoup的索引項 並不能利用遍歷的方法索引
在集合中每一個章節內容都存在set集合裡面
我們要通過set集合索引找出來所有的有用資訊,必須過濾出去換行,才能把每個內容都涵蓋
children集合是這樣的
所以我們要避免換行符引起的干擾。
這裡我們來看下children裡面到底是怎麼樣的
我們知道單獨一行 <li><a href="http://www.136book.com/doushen/cjekxe/">第196章 .邊境小鎮</a></li>
我們是可以用BeautifulSoup分析的 但是如果索引children這個集合則不能用了,
但是我們link遍歷的時候每一個都是一個小的子集 類似上面單獨一行,而這小小的一行則是BeautifulSoup中的元素
則 link.string link.text都是可以用的