我正在为this problem创建一个python解决方案,但我无法通过一些边缘案例。
我遇到的问题出现在像this这样的网页上,其中this link是应该提取的,因为它是括号外的第一个。{3}}。相反,有些文章是like this,其中链接出现在第一个括号之前。
我目前处理这些案例的方式是首先迭代第一段标记(字符串化版本)中的元素和文本,并检查首先在&#39;之间找到哪些(&#39; ;和一个<a>
。如果首先找到<a>
(意思是在到达括号之前),我只取这个链接。如果先找到括号,我等到括号关闭然后采取以下措施&#39;
实际上,我只是得到了第一个段落元素的直接子元素,可以通过以下方式完成:
soup = BeautifulSoup(response.content, "lxml")
soup.select_one("#mw-content-text > p > a")
我认为在这里工作的是使用这样的select语句从<p>
的开头到第一个括号中找到前缀中的第一个链接,或者(如果在那里没有&#39; ta链接)使用与我目前正在做的事情类似的东西,在紧密括号后面找到紧跟的链接:
`findNext('a').attrs['href']`
如果要使用这种方法,会出现多个问题,包括: 1.如何实际获得前缀直到第一个括号,只有&#39;的直接子元素。
有简化的方法吗?如果有更好的方法,它会是什么?
答案 0 :(得分:3)
当您需要检查括号或其他括号是否平衡时,此问题提醒我流行的算法和数据结构问题。对于这些问题,堆栈数据结构使用起来很方便。
因此,在这种情况下,如果有一个左括号,我们将推送到堆栈,如果有一个关闭的,则从中弹出。我们的有效链接是堆栈为空时的链接:
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
为#34;现代希腊语&#34;打印dialects
页面和linguistics
for&#34; Diglossia&#34;。这两种情况都得到了处理。