Beautiful Soup - 在文章中找到第一个链接
Posted
技术标签:
【中文标题】Beautiful Soup - 在文章中找到第一个链接【英文标题】:Beautiful Soup - Finding first link in an article 【发布时间】:2017-08-26 09:00:12 【问题描述】:我正在为this problem 创建一个 python 解决方案,但我无法通过一些边缘情况。
我遇到的问题出现在像this 这样的页面上,其中this link 是应该被提取的页面,因为它是括号外的第一个页面。相反,有些文章是like this,其中链接出现在第一个括号之前。
我目前处理这些情况的方式是首先遍历第一个段落标记(字符串化版本)中的元素和文本,并检查在 '(' 和 <a>
之间首先找到哪个。如果先找到<a>
(意思是在到达括号之前),我就拿那个链接。如果先找到括号,我等到括号关闭,然后再取下面的'
实际上,我只是获得了第一段元素的直接子元素,可以通过以下方式完成:
soup = BeautifulSoup(response.content, "lxml")
soup.select_one("#mw-content-text > p > a")
我认为在这里可行的是使用这样的选择语句来查找前缀中的第一个链接,从<p>
的开头直到第一个括号,或者(如果前缀中没有链接)find紧跟在右括号后面的链接使用类似于我目前正在做的事情:
`findNext('a').attrs['href']`
如果要使用这种方法,则会出现多个问题,包括: 1.如何实际获取前缀直到第一个括号只有'的直接子元素
有没有一种简化的方法来做到这一点?如果有更好的方法,会是什么?
【问题讨论】:
如何重新制定问题,例如“获取不在括号内的第一个链接 - 在它们之前或之后”?.. 【参考方案1】:这个问题让我想起了流行的算法和数据结构问题,当您需要检查括号或其他括号是否平衡时。对于这类问题,stack 数据结构 使用起来很方便。
因此,在这种情况下,如果有左括号,我们将推入堆栈,如果有右括号,则从其中弹出。对我们来说有效的链接将是 堆栈为空的链接:
import requests
from bs4 import BeautifulSoup, NavigableString, Tag
urls = [
"https://en.wikipedia.org/wiki/Modern_Greek",
"https://en.wikipedia.org/wiki/Diglossia"
]
with requests.Session() as session:
for url in urls:
response = session.get(url)
soup = BeautifulSoup(response.content, "html.parser")
stack = []
for child in soup.select_one("#mw-content-text > p").children:
if isinstance(child, NavigableString):
if "(" in child:
stack.append("(")
if ")" in child:
stack.pop()
if isinstance(child, Tag) and child.name == "a" and not stack:
print(child.get_text())
break
它为“现代希腊语”页面打印dialects
,为“Diglossia”打印linguistics
。两种情况都处理。
【讨论】:
是的,我也注意到了它对匹配括号问题的回忆。我最初的解决方案做了类似的事情。这是一个非常有创意的解决方案!我不太了解库函数,但它们似乎确实简化了代码。 其实像this这样的文章,主体不是第一个<p>
标签,而是第二个。如何唯一标识主体?这么多边缘案例!大声笑
@loremIpsum1771 有趣!如果我们在table
元素之后获得第一个p
,如果它存在,如果不存在,我们将在“内容”元素中获得第一个p
元素..?
@loremIpsum1771 顺便说一句,您是否考虑过使用 python *** API 客户端?...
Idk,似乎有无数的边缘情况需要处理。如果你很好奇,this 就是我最终所做的。以上是关于Beautiful Soup - 在文章中找到第一个链接的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac 上安装 Beautiful Soup 模块?
Beautiful Soup 4 find_all 找不到 Beautiful Soup 3 找到的链接