亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

python - 使用 BeautifulSoup 更有效地抓取網頁

python - 使用 BeautifulSoup 更有效地抓取網頁

Cats萌萌 2023-07-05 11:10:16
我正在編寫一個腳本來抓取維基百科頁面,其中包含這些名稱的名稱列表。具體來說,我正在抓取一個維基百科頁面,其中包含每個爵士鋼琴家的姓名列表(至少根據維基百科)。我想要做的是將本頁上所有鋼琴家的名字附加到一個列表中。以下是維基百科頁面的鏈接:https ://en.wikipedia.org/wiki/List_of_jazz_pianists我設法用 Beautiful Soup v4 找到了一個解決方案,但它看起來很笨重。讓我描述一下這個解決方案以及為什么我會實現它。(為了簡潔起見,我不會在這篇文章中包含 HTML 文件)import requestsimport bs4result = requests.get("https://en.wikipedia.org/wiki/List_of_jazz_pianists")soup = bs4.BeautifulSoup(result.text, "html.parser")bigList = soup.findAll('div', {'class' : 'div-col columns column-width'})bigList 是每個 div class = div-col columns column-width 的列表,因為這些 div 包含藝術家的實際姓名。artistList = []index = 0for nameTag in bigList[5].contents[1].contents:    if index % 2 == 0:        artistList.append(nameTag.contents[0].contents[0])            index += 1    print(artistList)這需要一些解釋。如果您查看 Wikipedia 頁面的 HTML 文件,將會有所幫助。bigList[5]給出 'F' 的所有姓氏,因為 F 是字母表中的第 6 個字符. bigList[5].contents給出一個包含 3 個元素的列表:一個換行轉義字符、F 的整個<li>列表,最后是另一個換行轉義字符. 因此訪問F 的 bigList[5].contents[1]整個列表。給出每個元素的列表,以換行轉義字符分隔。所以我的想法是,我將迭代此列表中的每個元素,僅采用偶數索引元素,因為奇數索引元素都是換行符轉義字符。<li>bigList[5].contents[1].contents<li>nameTag.contents給出一個由兩個元素組成的列表,鋼琴家的超鏈接和姓名,以及他們的出生日期 - 死亡日期. 所以我選擇該列表的第一個元素。最后,nameTag.contents[0].contents給出一個僅包含一個元素(鋼琴家的名字)的列表,因此我拉出該列表的唯一元素,以便將其作為字符串而不是嵌套列表附加到artistList。正如您所看到的,對于看起來應該更簡單的事情來說,這是一個極其復雜的過程。鑒于我對 bs4 和使用 python 進行網頁抓取總體來說是新手,我覺得有一個更好的解決方案。此外,我最終想從該頁面上鏈接的每個鋼琴家的頁面收集數據。我的解決方案不是很穩健或高效,我知道這會給我推進這個項目帶來問題。有更好的方法來做我想做的事情嗎?我真的很感謝您的幫助,對于帖子的長度以及任何其他不適當或非慣用的錯誤,我深表歉意 - 我是堆棧溢出的新手。謝謝!
查看完整描述

2 回答

?
jeck貓

TA貢獻1909條經驗 獲得超7個贊

您的解決方案可能有點過于依賴頁面的格式,盡管抓取維基百科總是很困難,因為帶有數據的元素沒有用標識符或類來標記它們保存的數據,所以您只能依賴于結構無論如何,表格保持不變。


您找到了正確的數據,但真正使藝術家鏈接與眾不同的是它們是元素<a>內的div-col <div>元素。


BS4 的一個更簡單的解決方案(考慮到您既需要藝術家姓名又需要他們頁面的鏈接):


from urllib import request

from bs4 import BeautifulSoup


with request.urlopen("https://en.wikipedia.org/wiki/List_of_jazz_pianists") as response:

    bs = BeautifulSoup(response, "html.parser")

    for div_col in bs.find_all('div', {'class': 'div-col'}):

        for artist_tag in div_col.find_all('a'):

            print(f'{artist_tag.text}, {artist_tag.attrs["href"]}')

請注意,這不使用第三方requests,而是標準urllib。


結果:


Irving Aaronson, /wiki/Irving_Aaronson

Anders Aarum, /wiki/Anders_Aarum

...

Bojan Zulfikarpa?i?, /wiki/Bojan_Zulfikarpa%C5%A1i%C4%87

Axel Zwingenberger, /wiki/Axel_Zwingenberger

如果您注重效率(或更確切地說是簡潔),那么這句話可能就是您喜歡的:


result = [(a.text, a.attrs['href'])

          for d in bs.find_all('div', {'class': 'div-col'})

          for a in d.find_all('a')]

result將是藝術家姓名和鏈接的元組列表,即[('Irving Aaronson', '/wiki/Irving_Aaronson'), ('Anders Aarum', '/wiki/Anders_Aarum'), ..]


查看完整回答
反對 回復 2023-07-05
?
吃雞游戲

TA貢獻1829條經驗 獲得超7個贊

找到后bigList,您可以使用此行替換其余行:

[row['title'] for row in bigList[5].find_all('a')]

要理解此代碼,請查看bigList[5]bigList[5].find_all('a')` 的輸出,然后也嘗試該行。

您可以類似地使用href代替title來查找網址。


查看完整回答
反對 回復 2023-07-05
  • 2 回答
  • 0 關注
  • 164 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號