1. 程式人生 > >python3 爬蟲面對如此多重複的標籤,應該怎麼爬才能爬到自己需要的資訊

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都是可以用的