使用Python BeautifulSoup / urllib2刮掉循环内循环的方法太慢了

时间:2014-08-19 05:17:25

标签: performance python-2.7 web-scraping beautifulsoup urllib2

我想抓一个网站的大部分。比方说,一般网址结构如下:

https://ExampleSite.com/XXXXX,其中X可以是任何数字或大写字母。 即https://ExampleSite.com/32E4Zhttps://ExampleSite.com/AA44P

总角色可能性为36,包括数字和字母。由于有5个随机时隙,因此总网址组合变得可怕36 ^ 5 = 60,466,176。在这些链接中,只有一小部分(20%)实际上有一个有效的页面,基于“examplesite.com”前面的url的其他组合返回无效的链接,我没有刮掉任何东西(但我想我仍然需要检查URL的组合是否有效并包含“特定标题”?)。

这是我的Python / BeautifulSoup代码正在运行,我的目标是通过这些网址组合并提取与“特定标题”匹配的有效链接:

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)

我的问题是处理速度慢,以及经历许多无效链接的负担。我发现每个网址需要大约1秒的时间来完成数学计算,60,466,176个组合将需要大约2年的时间才能使用我的计算机。这显然是不适用的。所以我的问题是:

  • 我在循环内循环错了吗?
  • 有什么方法可以避免快速或完全无法通过无效链接?
  • 正则表达式有帮助吗?
  • 我的下一步是实现多线程。虽然,我已经在其他程序中尝试过,但它的工作原理只会将处理时间缩短一半,所以仍然需要一整年的程序不间断运行。
  • 或者其他任何提示我可以加快这个过程吗?

1 个答案:

答案 0 :(得分:0)

这是一个I / O绑定任务。这意味着计算机的速度并不重要,因为花费最多时间(按数量级)是I / O(等待http请求)。可能没什么可以做的,以便更快地恢复请求。多线程会有所帮助,但正如你所说,只有2到4左右。

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

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

如果您真的尝试所有这些,那么一个选项可能是通过VPS托管公司创建大量虚拟服务器。根据它们限制某个域的流量的方式,如果您运行12台服务器,则可能会将其减少到一个月或更短。此外,这样您就不必拥有自己的机器。