【问题标题】:Scraping specific text form webpage从网页中抓取特定文本
【发布时间】:2020-06-17 06:36:22
【问题描述】:

我目前正在尝试从网页上抓取一些图表,但我是新手,不知道最佳解决方案。

<font color="DarkBLUE">
g:=Graph&lt;5|{ {2, 3}, {4, 5}, {1, 3}, {1, 2}, {1, 5}, {1, 4}, {2, 4}, {3, 5}, {2,
5}, {3, 4} }&gt;;</font>

我需要的是g:=Graph&lt;..&gt; 部分。 这是我到目前为止尝试过的(基于其他一些类似的问题):

tree = lh.fromstring(data)
rate = tree.xpath("//font[@color='DarkBLUE']")
graphurls.append(rate[0].text_content())

但问题是它会刮掉很多其他的东西。我认为这是可以做到的,因为它有一个独特的模式g:=Graph&lt;...&gt;,所以没有其他东西会被刮掉。

你能帮帮我吗?

【问题讨论】:

  • if text.strip().startswith("g:=Graph"): print(text.strip()[8:-2]) ?
  • 但问题是它会刮掉很多其他东西。 还有什么其他东西?请显示输出,尤其是因为您还没有分享minimal reproducible example

标签: python regex python-3.x web-scraping beautifulsoup


【解决方案1】:

第一种方法:你有字符串,所以你可以使用字符串的函数来过滤结果 - 即。

if text.strip().startswith('g:=Graph') :

例子:

data = '''<font color="DarkBLUE">
g:=Graph&lt;5|{ {2, 3}, {4, 5}, {1, 3}, {1, 2}, {1, 5}, {1, 4}, {2, 4}, {3, 5}, {2,
5}, {3, 4} }&gt;;</font>

<font color="DarkBLUE">h:=Other&lt;...&gt;;</font>'''

import lxml.html as lh

tree = lh.fromstring(data)
rate = tree.xpath("//font[@color='DarkBLUE']")

for item in rate:
    text = item.text_content()
    text = text.strip()
    if text.startswith('g:=Graph'):
        print(' OK:', text)
    else:
        print('NOT:', text)

第二种方法:可以使用xpath过滤

tree.xpath("//font[@color='DarkBLUE' and contains(text(), 'g:=Graph')]")

tree.xpath("//font[@color='DarkBLUE'][contains(text(), 'g:=Graph')]")

例子:

data = '''<font color="DarkBLUE">
g:=Graph&lt;5|{ {2, 3}, {4, 5}, {1, 3}, {1, 2}, {1, 5}, {1, 4}, {2, 4}, {3, 5}, {2,
5}, {3, 4} }&gt;;</font>

<font color="DarkBLUE">h:=Other&lt;...&gt;;</font>'''

import lxml.html as lh

tree = lh.fromstring(data)
rate = tree.xpath("//font[@color='DarkBLUE' and contains(text(), 'g:=Graph')]")

for item in rate:
    text = item.text_content()
    text = text.strip()
    print(text)

最终使用starts-with(),但数据中的文本在新行中,因此 xpath 中的文本在开始时需要\n

tree.xpath("//font[@color='DarkBLUE' and starts-with(text(), '\ng:=Graph')]")

顺便说一句: xpath cheatsheet

【讨论】:

    【解决方案2】:

    我会尝试使用正则表达式https://docs.python.org/3/library/re.html,您可以使用https://regex101.com/ 进行实验,直到找到正确的公式

    具体可以使用捕获组(\{\d+,\s*\d+\},?\s*)+查找重复序列

    "{2, 3}, {4, 5}, {1, 3}, {1, 2}, {1, 5}, {1, 4}, {2, 4}, {3, 5 },..."

    我重新阅读了您的问题,您可能已经知道所有这些,但是您也可以在美丽的汤中使用正则表达式https://www.crummy.com/software/BeautifulSoup/bs4/doc/#a-regular-expression

    【讨论】:

      【解决方案3】:

      一种方式是通过regex:

      import re
      
      graphs=re.findall("g:=.*;;", rate[0].text_content())
      

      这会捕获所有以“g:=”开头并以“;;”结尾的匹配项。它在字符串 rate[0].text_content() 中查找此类匹配项。

      注意: 将此应用于字符串,即.text_content(),而不是原始 HTML。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-04
        • 2010-09-29
        • 1970-01-01
        • 2019-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多