python下载网页中的所有文件

时间:2016-03-24 19:40:52

标签: python

我在代码下运行以下载网页中的所有文件:

import os
import urllib
from lxml import html

def main():
    os.chdir("Downloads/")
    url = "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_IEC_14496-26_2010_Bitstreams/DVD1/mpeg4audio-conformance/compressedMp4/"

    page = html.fromstring(urllib.urlopen(url).read())

    for link in page.xpath("//a"):
        filelink = "http://standards.iso.org/" + link.get("href")
        print "download",filelink
        runme("wget " + filelink)
    return

if __name__ == '__main__':
    main()

但我想这不是最好的,我怎样才能用更少的代码行来改进它?

2 个答案:

答案 0 :(得分:0)

Code Review这可能是一个更好的问题。简而言之,您的代码很好。如果有的话,您可能想要使用更多行。这是我尝试清理一些......但我添加了一行。

[0, 0, 2, 3]
[0, 1, 1, 2]
[0, 1, 4, 5]

如果我们打破这个功能,我们可以看到你需要做一些事情:

  1. 发送请求以获取网页内容。
  2. 将回复解析为HTML。
  3. 在结果树中搜索“a”标记。
  4. 根据“a”标记的import os from urllib import urlopen, basejoin from lxml import html def main(): os.chdir('Downloads') base_url = 'http://standards.iso.org' page_url = basejoin(base_url, 'ittf/PubliclyAvailableStandards/' 'ISO_IEC_14496-26_2010_Bitstreams/' 'DVD1/mpeg4audio-conformance/compressedMp4/') page_string = urlopen(page_url).read() page_html = html.fromstring(page_string) for link in page_html.getiterator('a'): file_url = basejoin(base_url, link.get('href')) if file_url.endswith('.mp4'): print 'Downloading: {}'.format(file_url) runme('wget {}'.format(file_url)) if __name__ == '__main__': main() 属性构建完整的文件路径。
  5. 在该位置下载文件。
  6. 我不知道任何组合其中一些步骤的模块。您的代码相对可读,我认为没有任何低效率。总之,我认为最大的错误是认为使用更少的行会改善你的代码(至少在这种情况下)。

答案 1 :(得分:0)

我会使用 urljoin 加入网址,您只需使用xpath获取href,您就不需要调用find:

import os
import urllib
from lxml import html
from urlparse  import urljoin
import grequests

def main():
    url = "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_IEC_14496-26_2010_Bitstreams/DVD1/mpeg4audio-conformance/compressedMp4/"

    page = html.fromstring(urllib.urlopen(url).read())
    reqs = (grequests.get((urljoin("http://standards.iso.org/", link))) for link in page.xpath("//a/@href"))
    for resp in grequests.imap(reqs):
        print(resp.content)

除此之外,我更愿意使用请求。

如果要进行异步,可以使用grequests lib:

namespace detail {
template<class T>struct tag{};

template<class T>
T Read(tag<T>) {
    return T{};
}

template<class T, std::size_t N>
std::array<T, N> Read(tag<std::array<T, N>>) {
    return {1,2,3};
}
}

template<class T>
auto Read() {
    return detail::Read(detail::tag<T>());
}

int main() {
    Read<std::array<int,5>>();
}