Python BeautifulSoup获取div子元素中所有href链接

7

我是 Python 的新手,一直在尝试从以下 HTML 代码中获取链接和内部文本:

<div class="someclass">
  <ul class="listing">
        <li>
          <a href="http://link1.com" title="">title1</a>
                </li>
        <li>
           <a href="http://link2.com" title="">title2</a>
                 </li>
        <li>
           <a href="http://link3.com" title="">title3</a>
                 </li>
        <li>
           <a href="http://link4.com" title="">title4</a>
                  </li>
  </ul>
</div>

我希望只获取来自href为http://link.com的所有链接以及它们的文本内容title

我尝试了以下代码:

    div = soup.find_all('ul',{'class':'listing'})
for li in div:
    all_li = li.find_all('li')
    for link in all_li.find_all('a'):
        print(link.get('href'))

但是我的运气不佳,有人能帮助我吗?
3个回答

9
问题在于你在第二个for循环中使用了find_all,它返回一个列表,而你应该使用find()
>>> for ul in soup.find_all('ul', class_='listing'):
...     for li in ul.find_all('li'):
...         a = li.find('a')
...         print(a['href'], a.get_text())
... 
http://link1.com title1
http://link2.com title2
http://link3.com title3
http://link4.com title4

您还可以使用CSS选择器来代替嵌套的forloop

>>> for a in soup.select('.listing li a'):
...     print(a['href'], a.get_text(strip=True))
... 
http://link1.com title1
http://link2.com title2
http://link3.com title3
http://link4.com title4

3

选择 ul 后获取所有 a 标签,然后从具有 title 属性和 href 的 a 标签中提取文本。

from bs4 import BeautifulSoup

html = """<div class="someclass">
  <ul class="listing">
        <li>
          <a href="http://link1.com" title="">title1</a>
                </li>
        <li>
           <a href="http://link2.com" title="">title2</a>
                 </li>
        <li>
           <a href="http://link3.com" title="">title3</a>
                 </li>
        <li>
           <a href="http://link4.com" title="">title4</a>
                  </li>
  </ul>
</div>"""

soup = BeautifulSoup(html,"lxml")
ul = soup.select("ul.listing")[0]
links = [a["href"] for a in ul.select("a[href]")]
text = [a.text for a in ul.select("a[title]")]

这将为您提供:

['title1', 'title2', 'title3', 'title4']
['http://link1.com', 'http://link2.com', 'http://link3.com', 'http://link4.com']

如果您实际上有多个匹配该类的ul:

uls = soup.select("ul.listing")
links = [a["href"] for ul in uls for a in ul.select("a[href]") ]
text = [a.text for ul in uls for a in  ul.select("a[title]")]

print(text)
print(links)

2
在你的代码中,all_li 实际上是 li 元素的一个列表。在下一行中,你试图把它当作单个元素使用:
all_li.find_all('a')

相反,你需要遍历all_li元素并在每个元素上调用find_all

类似这样的代码应该可以工作:

uls = soup.find_all('ul', {'class': 'listing'})
for ul in uls:
    for li in ul.find_all('li'):
        for link in li.find_all('a'):
            url = link.get('href')
            contents = link.text
            print (url, contents)

这将产生以下结果。
('http://link1.com', 'title1')
('http://link2.com', 'title2')
('http://link3.com', 'title3')
('http://link4.com', 'title4')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接