【问题标题】:Equivalent of wget in Python to download website and resources相当于Python中的wget下载网站和资源
【发布时间】:2012-02-10 00:21:34
【问题描述】:

2.5 年前在 Downloading a web page and all of its resource files in Python 中提出了同样的问题,但没有得到答案,而且“请参阅相关主题”实际上并不是在问同样的问题。

我想下载页面上的所有内容,以便仅从文件中查看。

命令

wget --page-requisites --domains=DOMAIN --no-parent --html-extension --convert-links --restrict-file-names=windows

正是我需要的。但是,我们希望能够将它与其他必须可移植的东西结合起来,因此要求它使用 Python。

我一直在看 Beautiful Soup、scrapy、各种蜘蛛张贴在这个地方,但这些似乎都以巧妙但特定的方式处理获取数据/链接。使用这些来做我想做的事情似乎需要大量的工作来处理找到所有资源,当我确定必须有一个简单的方法时。

非常感谢

【问题讨论】:

  • import urllib urllib.urlretrieve('somesite.com/file.whatever', '要下载的文件名')
  • 所以我知道我可以以这种方式下载单个文件,但我需要使用爬虫并设置许多条件来找到我想要的所有文件(一切都能够离线查看网站的一部分)。在 Python 中必须有一些下载网站和必要条件?
  • 您可以在 for 循环中使用解析函数来搜索下载文件中的链接(或从任何地方读取)
  • 这就是我们正在做的事情。老实说,我认为它会比找到页面规范(图像、css)更难,但指向它的链接在页面中可以找到并添加到集合中。
  • scrapy 似乎已经发展得非常灵活。你最近有没有试图让它做你想做的事?你能澄清你想要它不能做什么吗?

标签: python web-crawler wget


【解决方案1】:

您应该为手头的工作使用合适的工具。

如果您想爬取站点并将页面保存到磁盘,Python 可能不是最好的选择。当有人需要某个功能时,开源项目就会获得该功能,并且因为 wget 的工作做得非常好,所以没有人会费心尝试编写一个 python 库来替换它。

考虑到 wget 几乎可以在任何具有 Python 解释器的平台上运行,您是否有不能使用 wget 的原因?

【讨论】:

  • 你说得很好,没有人会为 python 写一个,我没有追求 wget 路线的唯一原因是我被要求用 Python 来做......我猜他们想减少依赖。我们现在几乎已经用 Python 编写了该工具以供我们狭隘地使用。如果允许,将在此处发布
【解决方案2】:

我的同事编写了这段代码,我相信这些代码是从其他来源拼凑而成的。我们的系统可能有一些特定的怪癖,但它应该可以帮助任何想要做同样事情的人

"""
    Downloads all links from a specified location and saves to machine.
    Downloaded links will only be of a lower level then links specified.
    To use: python downloader.py link
"""
import sys,re,os,urllib2,urllib,urlparse
tocrawl = set([sys.argv[1]])
# linkregex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?')
linkregex = re.compile('href=[\'|"](.*?)[\'"].*?')
linksrc = re.compile('src=[\'|"](.*?)[\'"].*?')
def main():
    link_list = []##create a list of all found links so there are no duplicates
    restrict = sys.argv[1]##used to restrict found links to only have lower level
    link_list.append(restrict)
    parent_folder = restrict.rfind('/', 0, len(restrict)-1)
    ##a.com/b/c/d/ make /d/ as parent folder
    while 1:
        try:
            crawling = tocrawl.pop()
            #print crawling
        except KeyError:
            break
        url = urlparse.urlparse(crawling)##splits url into sections
        try:
            response = urllib2.urlopen(crawling)##try to open the url
        except:
            continue
        msg = response.read()##save source of url
        links = linkregex.findall(msg)##search for all href in source
        links = links + linksrc.findall(msg)##search for all src in source
        for link in (links.pop(0) for _ in xrange(len(links))):
            if link.startswith('/'):
                ##if /xxx a.com/b/c/ -> a.com/b/c/xxx
                link = 'http://' + url[1] + link
            elif ~link.find('#'):
                continue
            elif link.startswith('../'):
                if link.find('../../'):##only use links that are max 1 level above reference
                    ##if ../xxx.html a.com/b/c/d.html -> a.com/b/xxx.html
                    parent_pos = url[2].rfind('/')
                    parent_pos = url[2].rfind('/', 0, parent_pos-2) + 1
                    parent_url = url[2][:parent_pos]
                    new_link = link.find('/')+1
                    link = link[new_link:]
                    link = 'http://' + url[1] + parent_url + link
                else:
                    continue
            elif not link.startswith('http'):
                if url[2].find('.html'):
                    ##if xxx.html a.com/b/c/d.html -> a.com/b/c/xxx.html
                    a = url[2].rfind('/')+1
                    parent = url[2][:a]
                    link = 'http://' + url[1] + parent + link
                else:
                    ##if xxx.html a.com/b/c/ -> a.com/b/c/xxx.html
                    link = 'http://' + url[1] + url[2] + link
            if link not in link_list:
                link_list.append(link)##add link to list of already found links
                if (~link.find(restrict)):
                ##only grab links which are below input site
                    print link ##print downloaded link
                    tocrawl.add(link)##add link to pending view links
                    file_name = link[parent_folder+1:]##folder structure for files to be saved
                    filename = file_name.rfind('/')
                    folder = file_name[:filename]##creates folder names
                    folder = os.path.abspath(folder)##creates folder path
                    if not os.path.exists(folder):
                        os.makedirs(folder)##make folder if it does not exist
                    try:
                        urllib.urlretrieve(link, file_name)##download the link
                    except:
                        print "could not download %s"%link
                else:
                    continue
if __name__ == "__main__":
    main()

感谢回复

【讨论】:

  • 我是编程新手,能告诉我如何使用这段代码吗?我还想下载链接到网页的所有内容并在本地打开它,我还被要求用 Python 来完成。
  • 我应该把我的链接放在哪里,我的页面保存在哪里?
  • 哎哟.. 使用 html 解析器
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多