是否可以使用urllib确定两个页面链接是否相关?

时间:2019-02-01 02:04:10

标签: python-3.x urllib

是否有可能找出网站是否为“子网站”。例如,使用urllib.urlparse刮擦Wikipedia Math page会得到以下netlocs:

en.wiktionary.org zu.wikipedia.org id.wikipedia.org

显然来自维基百科。但这也给了我

http://www.bbc.co.uk

这不是Wikipedia的派生词。问题是netloc只识别绝对URL。因此,我假定给定一个netloc,该链接位于已抓取页面的外部,而没有netloc的相对路径使我认为它完全属于当前被抓取的页面。

是否有一个urllib函数(或任何库)可以区分以下内容: zu.wikipedia.orgid.wikipedia.org,目前我认为我唯一剩下的选择是求助于正则表达式,而正则表达式的深度似乎不足以确定两个网站是否彼此相关或派生自其他网站。

1 个答案:

答案 0 :(得分:0)

您可能会在这里找到yarltldextract软件包的组合。 tldextract基于将URL的主机/ netloc分为3部分的逻辑:

  • 子域
  • 后缀(可以嵌套,带有多个“。”),例如“ .co.uk”或“ .ac.gov.br”(巴西国家/地区ac)

对于http://www.bbc.co.uk(您可以包括或排除该方案):

>>> import tldextract
>>> tldextract.extract('http://www.bbc.co.uk')
ExtractResult(subdomain='www', domain='bbc', suffix='co.uk')

现在要问的问题是:您似乎有兴趣同时使用路径的domain和相对绝对绝对特性来确定A是否为B的子站点。

首先,要解决此问题,您的问题中有一部分含糊不清:en.wiktionary.org在正式意义上是Wikipedia的子站点如何?因为它是相对URL?因为它里面有“ wiki”这个词?我假设它是前者,因此您的规则系统将变为:

  • 如果URL是相对的,则它是给定页面的子站点
  • 如果URL具有相同的域,那么它也是一个子站点
  • 第三条规则:“ // login.wikimedia.org”之类的情况也是相对的。从技术上讲,这是一条绝对路径,其中双斜杠后跟权限是“使用与父级使用的方案相同的方案”的简写。

功能:

from yarl import URL
import tldextract

def is_subsite(child, parent):
    u = URL(child)
    if not u.scheme and child.startswith('//'):
        return True
    if not u.is_absolute():
        return True
    return (tldextract.extract(child).domain ==
            tldextract.extract(parent).domain)

示例:

>>> # Operates on the pretence that `child` was found on `parent` page HTML
>>> is_subsite("/wiki/Category:Algebraic_geometry", 
...            "https://en.wikipedia.org/wiki/Portal:Mathematics")
True

>>> is_subsite("https://zu.wikipedia.org/wiki/Ikhasi_Elikhulu",
...            "https://en.wikipedia.org/wiki/Portal:Mathematics")
True

>>> is_subsite("//login.wikimedia.org",
...            "https://en.wikipedia.org/wiki/Portal:Mathematics")
True

一个免责声明:您可能想重新考虑传递类似“ zu.wikipedia.org”的内容,因为据我所知,根据RFC 3986,这实际上不是有效的URL。(它没有方案,并且不是还是相对的。我不认为它在https://en.wikipedia.org/wiki/Portal:Mathematics上是值得的。)这意味着URL("zu.wikipedia.org").is_absolute()将返回False。 (不要将yarl视为URL验证器,它更擅长URL操作和解析。