【问题标题】:Unable to convert a webpage to an html file where all the links will be absolute links无法将网页转换为所有链接都是绝对链接的 html 文件
【发布时间】:2021-03-11 19:40:20
【问题描述】:

我创建了一个脚本,它能够将网页转换为 html 文件,以便该文件看起来与该网页非常相似。我无法解决的唯一问题是 html 文件包含相对 url,如 /organizations/11-unilever?group=8831 而绝对链接是 https://en.eyeka.com/organizations/11-unilever?group=8831

我试过了:

import requests

link = "https://en.eyeka.com/contests/8831/results"

with requests.Session() as s:
    s.headers['user-agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
    res = s.get(link)
    
    with open("results.html", "wb") as f:
        f.write(res.content)

如何将网页转换为所有链接都是绝对链接(完整链接)的html文件?

【问题讨论】:

    标签: python html python-3.x web-scraping python-requests


    【解决方案1】:

    您可以使用正则表达式来查找和替换相对 URL:

    import re
    import requests
    import urllib3
    
    link = "https://en.eyeka.com/contests/8831/results"
    
    with requests.Session() as s:
        base_url = "://".join(
            urllib3.get_host(link)[:2]
        )  # get the base url (https://en.eyeka.com)
    
        s.headers[
            "user-agent"
        ] = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"
    
        text = s.get(link).text
    
        text = re.sub(
            r"(href=[\"\'])\/", f"\g<1>{base_url}/", text, 0, re.MULTILINE
        )  # replace all relative urls with absolute
    
        with open("results.html", "w", encoding="utf-8") as f:
            f.write(text)
    

    【讨论】:

    • 我刚才测试了你的脚本。链接似乎已转换为绝对链接,但这是我将光标悬停在 that link 上时看到的内容,因此当我单击此类链接时,它们会导致错误的地址。
    • 对不起,我忘记了:,已修复!
    【解决方案2】:

    我检查了您链接的页面,建议您检查脚本将在页面中找到的所有 'href="/' 并将其替换为 'href="https://en.eyeka.com/'

    所以:

    string_html.replace('href="/', 'href="https://en.eyeka.com/') 
    

    类似的东西。

    import requests
    
    link = "https://en.eyeka.com/contests/8831/results"
    
    with requests.Session() as s:
        s.headers['user-agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
        res = s.get(link)
    # convert to string
        res = res.text
    # add https ...
        res = res.replace('href="/', 'href="https://en.eyeka.com/')
    # encode 
        res = res.encode()  
        with open("results.html", "wb") as f:
            f.write(res)
    

    由于它们是相对路径,它们只能是https://en.eyeka.com/ + 相对路径。

    【讨论】:

    • 我尝试了您的解决方案并最终收到此错误f.write(res.content) AttributeError: 'str' object has no attribute 'content'
    • 那是因为 res 在 3 行之前被转换为字符串,所以它不再有“内容”。代码不会按原样工作。
    • 您的代码仍然无法正常工作。我建议运行你的代码。
    • 请再检查一次
    【解决方案3】:

    我的答案包括其他库,但它并没有假设它只适用于您提供的示例 url。它也不假定所有 url 都是相对的。

    import requests
    from urllib.parse import urlparse
    from bs4 import BeautifulSoup
    
    link = "https://en.eyeka.com/contests/8831/results"
    
    with requests.Session() as s:
        headers = {"user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"}
        s.headers = headers
        res = s.get(link)
    
    u = urlparse(res.url)
    domain = u.scheme + "://" + u.netloc  # extract domain will work with http or https since we are also extracting the scheme
    soup = BeautifulSoup(res.content, "html.parser")
    
    for a in soup.find_all('a'):  # loop through all links
        if "href" in a.attrs:  # not all links have an href tag
            if "http" not in a.attrs['href']:  # not all links are relative links
                a.attrs['href'] = domain + a.attrs['href']
    
    with open("results.html", "w", encoding='utf-8') as f:
        f.write(str(soup))
    

    【讨论】:

    • 它似乎在贡献者部分复制了基本 url,但该内容是通过 javascript 生成的,因此不清楚原因。要修复它,也许您可​​以删除包含用户/url 对的 json 对象中的基本 url。
    • 这不会修改脚本、样式表、链接和其他使页面在本地无法使用的内容。
    • @rafalou38 脚本和样式表使用绝对链接。如果您运行代码,它确实可以在本地运行。
    猜你喜欢
    • 2011-01-17
    • 2014-10-30
    • 2010-10-07
    • 2021-11-29
    • 2011-04-19
    • 2012-08-11
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多