【问题标题】:Tree traverse in PythonPython中的树遍历
【发布时间】:2020-01-07 07:30:11
【问题描述】:

我正在尝试编写一个脚本来找出 python 中网页的无响应链接。在尝试时,我发现 python 不支持多子节点。这是真的吗?或者我们可以访问多个子节点。

下面是我的代码sn-p:

import httplib2
import requests
from bs4 import BeautifulSoup, SoupStrainer

status = {}
response = {}
output = {}

def get_url_status(url, count):
    global links
    links = []
    print(url)
    print(count)
    if count == 0:
        return output
    else:
        # if url not in output.keys():
        headers = requests.utils.default_headers()
        req = requests.get(url, headers)
        if('200' in str(req)):
            # if url not in output.keys():
            output[url] = '200';
            for link in BeautifulSoup(req.content, parse_only=SoupStrainer('a')):
                if 'href' in str(link):
                    links.append(link.get('href'))

            # removing other non-mandotary links
            for link in links[:]:
                if "mi" not in link:
                    links.remove(link)

            # removing same url
            for link in links[:]:
                if link.rstrip('/') == url:
                    links.remove(link)

            # removing duplicate links
            links = list(dict.fromkeys(links))
            if len(links) > 0:
                for urllink in links:
                    return get_url_status(urllink, count-1)

result = get_url_status('https://www.mi.com/in', 5)
print(result)

在这段代码中,它只遍历子节点的左节点并跳过休息。像这样的东西。

而且输出并不令人满意,与实际相比非常少。

{'https://www.mi.com/in': '200', 'https://in.c.mi.com/': '200', 'https://in.c.mi.com/index.php': '200', 'https://in.c.mi.com/global/': '200', 'https://c.mi.com/index.php': '200'}

我知道,我在多个地方都缺乏,但我从来没有做过这种规模的事情,这是我第一次。如果这是一个新手问题,请原谅。

注意:我使用 mi.com 仅供参考。

【问题讨论】:

    标签: python python-3.x list python-2.7 tree


    【解决方案1】:

    乍一看,有一个明显的问题。

    if len(links) > 0:
        for urllink in links:
            return get_url_status(urllink, count-1)
    

    这个 sn-p 确实迭代links。它的迭代体中有return,这意味着它只会针对链接中的第一项运行,并立即返回它。还有另一个错误。如果在 count 达到 0 之前遇到没有链接的页面,则该函数只返回 None 而不是 output。请改为执行以下操作。

    if len(links):
        for urllink in links:
            get_url_status(urllink, count-1)
    return output
    

    if('200' in str(req)) 不是检查状态码的正确方法。它将检查正文中的子字符串“200”,而不是仅检查状态代码。应该是if req.status_code == 200

    另一件事是该函数只添加响应链接到output。如果要检查无响应的链接,是不是一定要添加不返回200状态码的链接?

    import requests
    from bs4 import BeautifulSoup, SoupStrainer
    
    status = {}
    response = {}
    output = {}
    
    def get_url_status(url, count):
        global links
        links = []
        # if url not in output.keys():
        headers = requests.utils.default_headers()
        req = requests.get(url, headers)
        if req.status_code == 200:
            # if url not in output.keys():
            output[url] = '200'
            if count == 0:
                return output
            for link in BeautifulSoup(req.content, parse_only=SoupStrainer('a'), parser="html.parser"):
                if 'href' in str(link):
                    links.append(link.get('href'))
    
            # removing other non-mandotary links
            for link in links:
                if "mi" not in link:
                    links.remove(link)
    
            # removing same url
            for link in links:
                if link.rstrip('/') == url:
                    links.remove(link)
    
            # removing duplicate links
            links = list(dict.fromkeys(links))
            print(links)
            if len(links):
                for urllink in links:
                    get_url_status(urllink, count-1)
            return output
    
    result = get_url_status('https://www.mi.com/in', 1)
    print(result)
    

    【讨论】:

    • 感谢@Hurried-Helpful。会试试这个,让你知道。是的,我也会添加其他响应代码的链接。我没有在 sn-p 中添加这个,因为代码已经很长了。我想我只需添加else: output[url] = req.status_code;即可实现这一目标。
    • 嗨@Hurried-Helpful,修改后它不会重复,只执行一次。有没有办法共享代码和输出。
    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多