如何使用BeautifulSoup刮取HTML中的链接

时间:2014-10-12 19:16:00

标签: python beautifulsoup scrape

我需要在html中下载一些链接。但我并不需要所有这些,我在这个网页的某些部分只需要很少一部分。 例如,在http://www.nytimes.com/roomfordebate/2014/09/24/protecting-student-privacy-in-online-learning中,我需要在debaters部分中添加链接。我打算使用BeautifulSoup,我看了一个链接的html:

<a href="/roomfordebate/2014/09/24/protecting-student-privacy-in-online-learning/student-data-collection-is-out-of-control" class="bl-bigger">Data Collection Is Out of Control</a>

这是我的代码:

r = requests.get(url)
data = r.text
soup = BeautifulSoup(data)
link_set = set()
for link in soup.find_all("a", class = "bl-bigger"):
    href = link.get('href')
    if href == None:
        continue
    elif '/roomfordebate/' in href:
        link_set.add(href)    
for link in link_set:
    print link 

这段代码应该给我带bl-greater类的所有链接。但实际上它什么也没有回报任何人都可以解释我的代码有什么问题或如何让它工作? 感谢

2 个答案:

答案 0 :(得分:0)

您需要使用对象而不是关键字参数调用该方法:

soup.find("tagName", { "class" : "cssClass" })

或使用执行CSS查询的.select方法:

soup.select('a.bl-bigger')

示例are in the docs,只搜索“.select”字符串。此外,不是编写整个脚本,而是快速获得一些带有ipython交互式shell的工作代码。

答案 1 :(得分:0)

当我从Chrome查看来源时,我根本看不到bl-bigger课程。可能是您的代码无效的原因?

让我们开始查看来源。整个Debaters部分似乎与divnytint-discussion-content放在一起。因此,使用BeautifulSoup,我们首先得到整个div

debaters_div = soup.find('div', class_="nytint-discussion-content")

再次从源代码中学习,似乎所有链接都在列表li标记内。现在,您只需查找所有li标记并在其中查找锚标记即可。您可以注意到的另一件事是,所有li标记都有类nytint-bylines-1

list_items = debaters_div.find_all("li", class_="nytint-bylines-1")
list_items[0].find('a')
# <a href="/roomfordebate/2014/09/24/protecting-student-privacy-in-online-learning/student-data-collection-is-out-of-control">Data Collection Is Out of Control</a>

所以,你的整个代码可以是:

link_set = set()
response = requests.get(url)
html_data = response.text
soup = BeautifulSoup(html_data)
debaters_div = soup.find('div', class_="nytint-discussion-content")
list_items = debaters_div.find_all("li", class_="nytint-bylines-1")

for each_item in list_items:
    html_link = each_item.find('a').get('href')
    if html_link.startswith('/roomfordebate'):
        link_set.add(html_link)

现在link_set将包含您想要的所有链接。从相关链接中,它将获取5个链接。

PS:link_set仅包含uri而非实际的html地址。因此,在将这些链接添加到http://www.nytimes.com之前,我会在开始时添加link_set。只需将最后一行更改为:

link_set.add('http://www.nytimes.com' + html_link)