【问题标题】:Webcrawler - Check if <a> tag with href is within an li tag using Beautiful soup?Webcrawler - 检查带有href的<a>标签是否在使用Beautiful soup的li标签内?
【发布时间】:2014-04-13 19:13:55
【问题描述】:

我正在用 Python 构建一个网络爬虫,使用漂亮的汤来爬取维基百科。问题是维基百科有很多我不想看的垃圾链接。

例如:

目标链接前带有#的链接

<li class="toclevel-1 tocsection-1">
  <a href="#Overview">
    <span class="tocnumber">1</span>
    <span class="toctext">Overview</span>
  </a>
</li>

讨论页面

<li class="nv-talk">
  <a href="/wiki/Template_talk:Data_structures" title="Template talk:Data structures">
    <span title="Discuss this template" style=";;background:none transparent;border:none;;">t</span>
  </a>
</li>

模板页面

<li class="nv-view">
  <a href="/wiki/Template:Data_structures" title="Template:Data structures">
    <span title="View this template" style=";;background:none transparent;border:none;;">v</span>
  </a>
</li>

等等……

现在,我将我已经访问过的所有链接存储在字典中,这样我就不会访问它们两次,所以我可以通过简单地检查链接是否正常来避免 目标链接 # 符号已在表中。

但是,谈话、模板和其他此类页面有点麻烦。

它们的独特之处在于它们总是出现在 &lt;li&gt; 标记中,带有一些类属性("nv-talk""nv-view" 等),但是我的爬虫依赖于查看 &lt;a&gt; 标记,所以我不'无权访问包含它的&lt;li&gt; 标记的属性。

此外,并非页面上的所有链接都包含在&lt;li&gt; 标记中,因此我不能简单地搜索&lt;li&gt; 标记。

有什么想法吗?

【问题讨论】:

    标签: python html beautifulsoup web-crawler


    【解决方案1】:

    你可以使用 BeautifulSoup 的find_parents() 方法。这将告诉您特定标签是否在具有指定属性的另一个标签内。在这种情况下,我们正在寻找另一个标签中的锚标签,该标签具有nv-talknv-view 类属性。

    演示:

    html = '''<li class="nv-talk"><a href="/wiki/Template_talk:Data_structures" title="Template talk:Data structures"><span title="Discuss this    template" style=";;background:none    transparent;border:none;;">t</span></a></li>    '''
    soup = BeautifulSoup(html)
    a_tag = soup.find('a')
    a_tag.find_parents(attrs={'class':'nv-talk'})
    

    给你:

    [<li class="nv-talk"><a href="/wiki/Template_talk:Data_structures" title="Template talk:Data    structures"><span style=";;background:none transparent;border:none;;"    title="Discuss this template">t</span></a></li>]
    

    对于您的网址列表中的每个锚标记,您可以检查find_parents() 是否返回一个空列表。如果是,则表示此链接不属于 Talk 或 Discuss 页面,因此对您的抓取而言是安全的。

    解决此问题的另一种方法是查看锚标记的href 属性是否以“http”或“https”开头。但我不完全确定它是否符合您的代码逻辑。我的意思是,以# 开头的具有href 属性的锚标记是指向同一页面内部分的链接。如果您需要忽略这些,您可以查找不以# 开头而是以httphttps 开头的锚标记。这就是我的意思:

    html = '''
    <li class="toclevel-1 tocsection-1"><a href="#Overview"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
    <li class="toclevel-1 tocsection-1"><a href="http://www.google.com"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
    <li class="toclevel-1 tocsection-1"><a href="#Overview"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
    '''
    soup = BeautifulSoup(html)
    a_tag = soup.find('a', attrs={'href': re.compile(r'^http.*')})
    

    这只会为您提供以 http 开头的链接。

    【讨论】:

    • 听起来可能可行。使用 http 与 https 解决问题是什么意思? (我对 html 解析有点陌生)
    • 谢谢,我马上试试。
    • @Kittenmittons 当然。如果它解决了您的问题,请稍后接受答案。谢谢。
    • 会的。好的,这适用于具有类属性的 li 标签。如果我执行以下形式: a_tag.find_parents(attrs={'class': re.compile('nv')}) ... 如果我想查找多个属性怎么办?就像寻找一个 id 属性(一个例子是
    • 。有没有办法在同一个语句中搜索多个属性(我的语法有问题),或者我应该只需将它们放在单独的语句中,然后将它们“或”在一起?
  • @Kittenmittons 这有关于它的信息 - stackoverflow.com/questions/18725760/…
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签