2

我需要将 HTML 页面中的相对 URL 转换为绝对 URL。我正在使用 pyquery 进行解析。

例如,这个页面http://govp.info/o-gorode/gorozhane在源代码中有相对 URL,比如

<a href="o-gorode/gorozhane?page=2">2</a>

(这是页面底部的分页链接)。我正在尝试使用make_links_absolute()

import requests
from pyquery import PyQuery as pq

page_url = 'http://govp.info/o-gorode/gorozhane'
resp = requests.get(page_url)
page = pq(resp.text)

page.make_links_absolute(page_url)

但这似乎打破了相对链接:

print(page.find('a[href*="?page=2"]').attr['href'])

# prints            http://govp.info/o-gorode/o-gorode/gorozhane?page=2
# expected value    http://govp.info/o-gorode/gorozhane?page=2

如您所见o-gorode,最终 URL 中间有两倍,肯定会产生 404 错误。

谷歌浏览器在 URL 转换方面做得很好

pyquery 内部使用urljoin标准urllib.parse模块,有点像这样:

from urllib.parse import urljoin
urljoin('http://example.com/one/', 'two')

# -> 'http://example.com/one/two'

没关系,但是有很多网站都有,嗯,具有完整路径的不寻常的相对链接。

在这种情况下urljoin会给我们一个无效的绝对链接:

urljoin('http://govp.info/o-gorode/gorozhane', 'o-gorode/gorozhane?page=2')

# -> 'http://govp.info/o-gorode/o-gorode/gorozhane?page=2'

我相信这样的相对链接不是很有效,但谷歌浏览器处理它们没有问题;所以我想这在网络上是很正常的。

有什么建议可以解决这个问题吗?我试过furl了,但它的加入也是一样的。

4

1 回答 1

2

在这种特殊情况下,相关页面包含

<base href="http://govp.info/"/>

它指示浏览器使用它来解析任何相关链接。该<base>元素是可选的,但如果存在,则必须使用它而不是页面的实际 URL。

为了像浏览器那样做,提取基本 href 并在make_links_absolute().

import requests
from pyquery import PyQuery as pq

page_url = 'http://govp.info/o-gorode/gorozhane'
resp = requests.get(page_url)
page = pq(resp.text)

base = page.find('base').attr['href']
if base is None:
    base = page_url    # the page's own URL is the fallback

page.make_links_absolute(base)

for a in page.find('a'):
     if 'href' in a.attrib and 'govp.info' in a.attrib['href']:
         print(a.attrib['href'])

印刷

http://govp.info/assets/images/map.png
http://govp.info/podpiska.html
http://govp.info/
http://govp.info/#order
...
http://govp.info/o-gorode/gorozhane
http://govp.info/o-gorode/gorozhane?page=2
http://govp.info/o-gorode/gorozhane?page=3
http://govp.info/o-gorode/gorozhane?page=4
http://govp.info/o-gorode/gorozhane?page=5
http://govp.info/o-gorode/gorozhane?page=6
http://govp.info/o-gorode/gorozhane?page=2
http://govp.info/o-gorode/gorozhane?page=17
http://govp.info/bannerclick/264
...
http://doska.govp.info/cat-biznes-uslugi/
http://doska.govp.info/cat-transport/legkovye-avtomobili/
http://doska.govp.info/
http://govp.info/

这似乎是正确的。

于 2020-06-04T13:53:10.317 回答