【问题标题】:How to grab accurate titles from web pages without including site data如何在不包含站点数据的情况下从网页中获取准确的标题
【发布时间】:2020-07-12 20:38:51
【问题描述】:

我发现this link [和其他一些人] 谈到了一些关于阅读 html 的 BeautifulSoup。它主要做我想做的事,抓取网页的标题。

def get_title(url):
    html = requests.get(url).text
    if len(html) > 0:
        contents = BeautifulSoup(html)
        title = contents.title.string
        return title
    return None

我遇到的问题是,有时文章会在最后附上“-some_data”的元数据。一个很好的例子是this link BBC 体育文章的标题为

杰克查尔顿:1966 年英格兰世界杯冠军去世,享年 85 岁 - BBC 体育

我可以做一些简单的事情,比如在最后一个“-”字符之后切断任何东西

title = title.rsplit(', ', 1)[0]

但这假设任何元数据都存在于“-”值之后。我不想假设永远不会有标题以“-part_of_title”结尾的文章

我找到了Newspaper3k library,但它肯定超出了我的需要——我只需要获取一个标题并确保它与用户发布的内容相同。给我指点 Newspaper3k 的朋友也提到它可能有问题,并且并不总是能正确找到标题,所以如果可能的话,我会倾向于使用其他东西。

我目前的想法是继续使用 BeautifulSoup 并添加 fuzzywuzzy 老实说这也有助于解决轻微的拼写错误或标点符号差异。但是,我当然更愿意从包含与准确标题进行比较的地方开始。

【问题讨论】:

  • 你已经有了准确的标题。该标题是由网站的创建者选择的。如果您只想获取标题的相关部分,则需要定义相关内容。即使是人类也无法可靠地为每一页做到这一点,更不用说计算机了。您可以做的是检测许多页面的一部分(开始或结束)始终相同并删除该部分。
  • 这在不同站点之间并不一致,所以我不一定有一个模式。但是,虽然我可能有一个“准确”的标题,但用户在单击链接时看到的标题不包括该标题。我想要的是用户打开链接时会看到的标题

标签: python


【解决方案1】:

这是 reddit 处理获取标题数据的方式。

https://github.com/reddit-archive/reddit/blob/40625dcc070155588d33754ef5b15712c254864b/r2/r2/lib/utils/utils.py#L255

def extract_title(data):
    """Try to extract the page title from a string of HTML.
    An og:title meta tag is preferred, but will fall back to using
    the <title> tag instead if one is not found. If using <title>,
    also attempts to trim off the site's name from the end.
    """
    bs = BeautifulSoup(data, convertEntities=BeautifulSoup.HTML_ENTITIES)
    if not bs or not bs.html.head:
        return
    head_soup = bs.html.head

    title = None

    # try to find an og:title meta tag to use
    og_title = (head_soup.find("meta", attrs={"property": "og:title"}) or
                head_soup.find("meta", attrs={"name": "og:title"}))
    if og_title:
        title = og_title.get("content")

    # if that failed, look for a <title> tag to use instead
    if not title and head_soup.title and head_soup.title.string:
        title = head_soup.title.string

        # remove end part that's likely to be the site's name
        # looks for last delimiter char between spaces in strings
        # delimiters: |, -, emdash, endash,
        #             left- and right-pointing double angle quotation marks
        reverse_title = title[::-1]
        to_trim = re.search(u'\s[\u00ab\u00bb\u2013\u2014|-]\s',
                            reverse_title,
                            flags=re.UNICODE)

        # only trim if it won't take off over half the title
        if to_trim and to_trim.end() < len(title) / 2:
            title = title[:-(to_trim.end())]

    if not title:
        return

    # get rid of extraneous whitespace in the title
    title = re.sub(r'\s+', ' ', title, flags=re.UNICODE)

    return title.encode('utf-8').strip()

【讨论】:

  • 面临同样的问题。感谢您的代码;这很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2020-04-09
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
相关资源
最近更新 更多