gpt4 book ai didi

python - 查找与 BeautifulSoup(python)最近的链接

转载 作者:太空狗 更新时间:2023-10-29 22:09:50 25 4
gpt4 key购买 nike

我正在做一个小项目,我在其中提取政治领导人在报纸上的出现。有时会提到一位政客,但没有 parent 或 child 有联系。 (我猜是由于语义错误的标记)。

所以我想创建一个函数,可以找到最近的链接,然后提取它。在下面的例子中,搜索字符串是 Rasmussen,我想要的链接是:/307046

#-*- coding: utf-8 -*-

from bs4 import BeautifulSoup
import re

tekst = '''
<li>
<div class="views-field-field-webrubrik-value">
<h3>
<a href="/307046">Claus Hjort spiller med mrkede kort</a>
</h3>
</div>
<div class="views-field-field-skribent-uid">
<div class="byline">Af: <span class="authors">Dennis Kristensen</span></div>
</div>
<div class="views-field-field-webteaser-value">
<div class="webteaser">Claus Hjort Frederiksens argumenter for at afvise
trepartsforhandlinger har ikke hold i virkeligheden. Hans rinde er nok
snarere at forberede det ideologiske grundlag for en Løkke Rasmussens
genkomst som statsministe
</div>
</div>
<span class="views-field-view-node">
<span class="actions">
<a href="/307046">Ls mere</a>
|
<a href="/307046/#comments">Kommentarer (4)</a>
</span>
</span>
</li>
'''

to_find = "Rasmussen"
soup = BeautifulSoup(tekst)
contexts = soup.find_all(text=re.compile(to_find))

def find_nearest(element, url, direction="both"):
"""Find the nearest link, relative to a text string.
When complete it will search up and down (parent, child),
and only X levels up down. These features are not implemented yet.
Will then return the link the fewest steps away from the
original element. Assumes we have already found an element"""

# Is the nearest link readily available?
# If so - this works and extracts the link.
if element.find_parents('a'):
for artikel_link in element.find_parents('a'):
link = artikel_link.get('href')
# sometimes the link is a relative link - sometimes it is not
if ("http" or "www") not in link:
link = url+link
return link
# But if the link is not readily available, we will go up
# This is (I think) where it goes wrong
# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
if not element.find_parents('a'):
element = element.parent
# Print for debugging
print element #on the 2nd run (i.e <li> this finds <a href=/307056>
# So shouldn't it be caught as readily available above?
print u"Found: %s" % element.name
# the recursive call
find_nearest(element,url)

# run it
if contexts:
for a in contexts:
find_nearest( element=a, url="http://information.dk")

下面的直接调用有效:

print contexts[0].parent.parent.parent.a['href'].encode('utf-8')

作为引用,整个抱歉的代码都在 bitbucket 上:https://bitbucket.org/achristoffersen/politikere-i-medierne

(附注:使用 BeautifullSoup 4)


编辑:SimonSapin 要求我定义最近:“最近”是指距离搜索词在任一方向上嵌套层数最少的链接。在上面的文本中,由基于 drupal 的报纸站点生成的 a href 既不是找到搜索字符串的标签的直接父代也不是子代。所以 BeautifullSoup 找不到。

我怀疑“最少的字符数”通常也能奏效。在那种情况下,解决方案可以与 find 和 rfind 一起被破解 - 但我真的很想通过 BS 来做到这一点。因为这会起作用:contexts[0].parent.parent.parent.a['href'].encode('utf-8') 因此必须可以将其概括为脚本。

编辑:也许我应该强调我正在寻找 BeautifulSoup 解决方案。我认为,按照 @erik85 的建议,将 BS 与自定义/简单呼吸优先搜索相结合会很快变得困惑。

最佳答案

有人可能会想出一个适用于复制和粘贴的解决方案,您会认为这可以解决您的问题。不过,您的问题不是代码!这是你的策略。有一个称为“分而治之”的软件设计原则,您应该在重新设计代码时应用该原则:将将 HTML 字符串解释为树/图的代码与搜索最近的节点(可能是 breadth-first-search)分开。您不仅会学会设计更好的软件,而且您的问题可能会不复存在

我认为你很聪明,可以自己解决这个问题,但我也想提供一个框架:

def parse_html(txt):
""" reads a string of html and returns a dict/list/tuple presentation"""
pass

def breadth_first_search(graph, start, end):
""" finds the shortest way from start to end
You can probably customize start and end to work well with the input you want
to provide. For implementation details see the link in the text above.
"""
pass

def find_nearest_link(html,name):
"""putting it all together"""
return breadth_first_search(parse_html(html),name,"link")

PS:这样做也适用另一个原则,但是从数学上讲:假设有一个问题您不知道解决方案(找到靠近所选子字符串的链接)并且有一组问题您知道解决方案到(图形遍历),然后尝试转换你的问题以匹配你可以解决的问题组,这样你就可以只使用基本的解决方案模式(甚至可能已经在你选择的语言/框架中实现了)你就完成了.

关于python - 查找与 BeautifulSoup(python)最近的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11776157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com