Performance 使用Python BeautifulSoup/urllib2在循环内部刮取循环太慢

Performance 使用Python BeautifulSoup/urllib2在循环内部刮取循环太慢,performance,python-2.7,web-scraping,beautifulsoup,urllib2,Performance,Python 2.7,Web Scraping,Beautifulsoup,Urllib2,我想刮一个网站的很大一部分。例如,一般url结构如下所示: ,其中X可以是任何数字或大写字母。 i、 e 包括数字和字母在内,总共有36个字符。因为有5个随机的时隙,所以总的url组合变成了一个可怕的36^5=60466176。在这些链接中,只有一小部分20%实际上有一个有效的页面,其他基于examplesite.com首页的url组合返回无效链接,我没有刮取任何内容,但我想我仍然需要检查url组合是否有效,是否包含特定的标题 这是我的Python/BeautifulSoup代码,我的目标是浏览

我想刮一个网站的很大一部分。例如,一般url结构如下所示:

,其中X可以是任何数字或大写字母。 i、 e

包括数字和字母在内,总共有36个字符。因为有5个随机的时隙,所以总的url组合变成了一个可怕的36^5=60466176。在这些链接中,只有一小部分20%实际上有一个有效的页面,其他基于examplesite.com首页的url组合返回无效链接,我没有刮取任何内容,但我想我仍然需要检查url组合是否有效,是否包含特定的标题

这是我的Python/BeautifulSoup代码,我的目标是浏览这些url组合并提取与特定标题匹配的有效链接:

import urllib2
import re
import csv
from bs4 import BeautifulSoup
import threading

def get_Siteinfo(varURLpart1, varURLpart2, varURLpart3, varURLpart4, varURLpart5):

    for loop1 in range(0, varURLpart1): 
        for loop2 in range(0, varURLpart2):
            for loop3 in range(0, varURLpart3):
                for loop4 in range(0, varURLpart4):
                    for loop5 in range(0, varURLpart5):

                        URLchar = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 
                            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
                            "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] # len(URLchar) = 36

                        url1 = "https://ExampleSite.com/"
                        urlComplete  = url1 + str(URLchar[loop1]) + str(URLchar[loop2]) + \
                            str(URLchar[loop3]) + str(URLchar[loop4]) + str(URLchar[loop5])

                        page = urllib2.urlopen(urlComplete)
                        soup_SomeSiteURL = BeautifulSoup(page, "lxml")
                        page.close()

                        Subhead = soup_SomeSiteURL.find("span", class_="subhead")
                        if Subhead: # If-statement solution; if "subhead" class is found
                            SubheadString = Subhead.get_text(strip=True) # then extract the string
                            if SubheadString == "Specific heading":
                                saveFile = open('SomeSiteValidURLs.csv', 'a')
                                saveFile.write(str(urlComplete)+'\n')
                                saveFile.close()

                        loop5 += 1
                    loop4 += 1
                loop3 += 1
            loop2 += 1
        loop1 += 1

get_Siteinfo(36, 36, 36, 36, 36)
我的问题是处理速度慢和通过许多无效链接的负担。我发现每个url都需要大约1秒的时间,要计算出来,60466176个组合将需要大约2年的时间,我的电脑一直开着。这显然是不适用的。因此,我的问题是:

我在循环中使用循环时做错了吗? 有没有办法避免快速或完全通过无效链接的需要? 正则表达式会有帮助吗? 我的下一步是实现多线程。不过,我在其他程序中也尝试过,虽然它有效,但它只将处理时间减少了一半,所以它仍然需要一整年不间断地运行程序。 或者其他我可以加快这个过程的技巧?
这是一个I/O绑定任务。这意味着计算机的速度无关紧要,因为按数量级计算,占用时间最多的是等待http请求的I/O。要更快地返回请求,您可能无法做很多事情。多线程将有所帮助,但正如您所说,只有2到4倍左右

您最好的选择是查看是否可以找到有效URL的列表,而无需全部尝试。也许你可以在网站的其他地方找到这个?如果没有,请联系网站管理员

除此之外,这与尝试使用所有可能的密码入侵某人的帐户没有多大区别


如果您真的想尝试所有这些,那么一个选择可能是通过VPS托管公司创建大量虚拟服务器。根据他们如何限制特定域的流量,如果您有12台服务器在运行,您可能会将流量减少到一个月或更少。而且,这样你就不必让自己的机器来做了。

谢谢你的建议,我会进一步研究它们。我想到了一个可能的解决办法。例如,与其在一个python脚本中执行所有循环,不如创建12个脚本,覆盖所有60466176组合,不重叠。然后不间断地运行这12个脚本一个月,然后将csv文件合并成一个。您认为这是可行的,并且速度会提高12倍吗?不,这不会比多线程更有优势,因为您的连接一次可以处理的http通信量是有限的。另外,要小心,因为ExampleSite可能会在收到大量来自您的请求时禁止您的IP。