为什么我根据迭代数组元素的位置得到不同长度的输出元素数组?

Why do I get different length of array of outputed elements depending on the position of elements of iterating array?

因此,这段代码的目的是提供页面上的 URL 列表,但我发现输出的 URL 数量 取决于元素在页面中的位置迭代时使用的数组,即 params = ["src", "href"]

该代码包含导入了Requests库的工作程序,使用了requests.get()、response.text以及列表和循环等结构。 要复制代码,请使用 Expand Snippet 按钮。


问题:

  1. 为什么我在params数组中的0-s位置使用"src"时得到8个url136 urls 当我在 params 数组中的 0-s 位置使用 "href" 时,请参阅:

  1. 如何获取数组all_urls中的所有元素(src和href)?

import requests


domain = "https://www.python.org/"


response = requests.get(domain)
page = response.text
all_urls = set()
params = ["src", "href"]


def getURL(page, param):

    start_link = page.find(param)
    if start_link == -1:
        return None, 0
    start_quote = page.find('"', start_link)
    end_quote = page.find('"', start_quote + 1)
    url = page[start_quote + 1: end_quote]
    return url, end_quote

for param in params:

    while True:
        url, n = getURL(page, param)
        page = page[n:]
        #count += 1
        if url:
            if url.startswith('/') or url.startswith('#!'):
                all_urls.add(domain + url)
            elif url.startswith('http'):
                all_urls.add(url)
            else:
                continue
        else:
            break


print("all urls length:", len(all_urls))

回答您的问题:

1- 发生这种情况是因为您在循环

中使用了 page 变量
url, n = getURL(page, param)
page = page[n:] // this one here

这只是在每次迭代后对页面字符串进行切片并将其重新分配给同一个变量,因此您在每次迭代中都会丢失一个块。当您到达最后一个 srchref 时,您可能已经到了文档的末尾。

2- 一个非常快速的代码修复方法是为每个新 param:

重置 page
for param in params:
    page = response.text
    while True:
        url, n = getURL(page, param)
        page = page[n:]
        ....

不过

有更好的方法来处理 HTML。为什么不直接使用 HTML Parser 来完成这项任务?

例如你可以使用BeautifulSoup4,例如:(不是最佳代码,未经测试,只是为了快速演示)

import requests
from bs4 import BeautifulSoup

response = requests.get("https://www.python.org/")
page = BeautifulSoup(response.text, "html.parser")

all_urls = list()

elements = page.find_all(lambda tag: tag.has_attr('src') or tag.has_attr('href'))

for elem in elements:
    if elem.has_attr('src'):
        all_urls.append(elem['src'])
    elif elem.has_attr('href'):
        all_urls.append(elem['href'])

print("all urls with dups length:", len(all_urls))
print("all urls w/o dups length:", len(set(all_urls)))