2016-03-24 61 views
1

我運行下面的代碼來下載網頁中的所有文件,所有文件:蟒蛇下載網頁中的

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() 

但我想這是不是最好的,我怎麼能以更少的代碼行改進呢?

+0

添加代碼,使用網址,以獲取主機名,不要硬編碼。 – lucky1928

+0

如果你唯一的目標是減少行數,除了可能使用一些更加現代化的圖書館來輔助像'python-requests'和'BeautifulSoup 4'這樣的工作,或者甚至像Scrapy'這樣的一些完整的工具集,你的唯一目標就是減少行數。然而,如果你想爲速度和/或更少的錯誤進行優化,那麼我首先要問的是你的'runme'是否是異步執行的,當'filelink'是一個畸形的鏈接時它是否處理。 – woozyking

回答

0

我會用urljoin加入網址,你可以只使用XPath來獲得的HREFs,你並不需要調用發現:

import urllib 
from lxml import html 
from urlparse import urljoin 
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()) 

    for link in page.xpath("//a/@href"): 
     runme("wget " + urljoin("http://standards.iso.org/", link)) 

除此之外,我更願意用要求。

如果你想異步,你可以利用grequests LIB:

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) 
0

對於Code Review這可能是一個更好的問題。總之,你的代碼很好。如果有的話,你可能想要使用更多的線。這是我嘗試清理一些...但我已經添加了幾行。

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() 

如果我們打破了這個功能了,我們可以看到,你需要做的幾件事情:

  1. 發送的請求得到一個網頁的內容。
  2. 將響應解析爲HTML。
  3. 在結果樹中搜索「a」標籤。
  4. 構建「a」標籤的href屬性的完整文件路徑。
  5. 在該位置下載文件。

我不知道任何將結合這些步驟的模塊。你的代碼相對可讀,我沒有看到任何低效率。總之,我認爲最大的錯誤是認爲使用更少的行可以改善您的代碼(至少在這種情況下)。