【Python】Python的urllib模塊、urllib2模塊批量進(jìn)行網(wǎng)頁(yè)下載文件
由于需要從某個(gè)網(wǎng)頁(yè)上下載一些PDF文件,但是需要下載的PDF文件有幾百個(gè),所以不可能用人工點(diǎn)擊來(lái)下載。正好Python有相關(guān)的模塊,所以寫了個(gè)程序來(lái)進(jìn)行PDF文件的下載,順便熟悉了Python的urllib模塊和ulrllib2模塊。
1、問(wèn)題描述
需要從http://www.cvpapers.com/cvpr2014.html上下載幾百個(gè)論文的PDF文件,該網(wǎng)頁(yè)如下圖所示:
2、問(wèn)題解決
通過(guò)結(jié)合Python的urllib模塊和urllib2模塊來(lái)實(shí)現(xiàn)自動(dòng)下載。代碼如下:
test.py
#!/usr/bin/python
# -*- coding:utf-8 -*-
import urllib #導(dǎo)入urllib模塊
import urllib2 #導(dǎo)入urllib2模塊
import re #導(dǎo)入正則表達(dá)式模塊:re模塊
def getPDFFromNet(inputURL):
req = urllib2.Request(inputURL)
f = urllib2.urlopen(req) #打開(kāi)網(wǎng)頁(yè)
localDir = 'E:\downloadPDF\\' #下載PDF文件需要存儲(chǔ)在本地的文件夾
urlList = [] #用來(lái)存儲(chǔ)提取的PDF下載的url的列表
for eachLine in f: #遍歷網(wǎng)頁(yè)的每一行
line = eachLine.strip() #去除行首位的空格,習(xí)慣性寫法
if re.match('.*PDF.*', line): #去匹配含有“PDF”字符串的行,只有這些行才有PDF下載地址
wordList = line.split('\"') #以"為分界,將該行分開(kāi),這樣就將url地址單獨(dú)分開(kāi)了
for word in wordList: #遍歷每個(gè)字符串
if re.match('.*\.pdf$', word): #去匹配含有“.pdf”的字符串,只有url中才有
urlList.append(word) #將提取的url存入列表
for everyURL in urlList: #遍歷列表的每一項(xiàng),即每一個(gè)PDF的url
wordItems = everyURL.split('/') #將url以/為界進(jìn)行劃分,為了提取該P(yáng)DF文件名
for item in wordItems: #遍歷每個(gè)字符串
if re.match('.*\.pdf$', item): #查找PDF的文件名
PDFName = item #查找到PDF文件名
localPDF = localDir + PDFName #將本地存儲(chǔ)目錄和需要提取的PDF文件名進(jìn)行連接
try:
urllib.urlretrieve(everyURL, localPDF) #按照url進(jìn)行下載,并以其文件名存儲(chǔ)到本地目錄
except Exception,e:
continue
getPDFFromNet('http://www.cvpapers.com/cvpr2014.html')
注意:
(1)第1、6、8、23行分別多謝了一個(gè)“\”來(lái)進(jìn)行轉(zhuǎn)義;
(2)第27行的urlretrieve函數(shù)有3個(gè)參數(shù):第一個(gè)參數(shù)就是目標(biāo)url;第二個(gè)參數(shù)是保存的文件絕對(duì)路徑(含文件名),該函數(shù)的返回值是一個(gè)tuple(filename,header),其中的filename就是第二個(gè)參數(shù)filename。如果urlretrieve僅提供1個(gè)參數(shù),返回值的filename就是產(chǎn)生的臨時(shí)文件名,函數(shù)執(zhí)行完畢后該臨時(shí)文件會(huì)被刪除參數(shù)。第3個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),當(dāng)連接上服務(wù)器、以及相應(yīng)的數(shù)據(jù)塊傳輸完畢的時(shí)候會(huì)觸發(fā)該回調(diào)。其中回調(diào)函數(shù)名稱可任意,但是參數(shù)必須為三個(gè)。一般直接使用reporthook(block_read,block_size,total_size)定義回調(diào)函數(shù),block_size是每次讀取的數(shù)據(jù)塊的大小,block_read是每次讀取的數(shù)據(jù)塊個(gè)數(shù),taotal_size是一一共讀取的數(shù)據(jù)量,單位是byte??梢允褂胷eporthook函數(shù)來(lái)顯示讀取進(jìn)度。
如果想顯示讀取進(jìn)度,則可以講第三個(gè)參數(shù)加上,將上述程序第27行改為如下:
urllib.urlretrieve(everyURL, localPDF, reporthook=reporthook)
而reporthook回調(diào)函數(shù)的代碼如下:
def reporthook(block_read,block_size,total_size): if not block_read: print "connection opened"; return if total_size<0: #unknown size print "read %d blocks (%dbytes)" %(block_read,block_read*block_size); else: amount_read=block_read*block_size; print 'Read %d blocks,or %d/%d' %(block_read,block_read*block_size,total_size);
綜上所述,這就是一個(gè)簡(jiǎn)單的從網(wǎng)頁(yè)抓取數(shù)據(jù)、下載文件的小程序,希望對(duì)正在學(xué)習(xí)Python的同學(xué)有幫助。謝謝!
相關(guān)文章
Python中使用多進(jìn)程來(lái)實(shí)現(xiàn)并行處理的方法小結(jié)
本篇文章主要介紹了Python中使用多進(jìn)程來(lái)實(shí)現(xiàn)并行處理的方法小結(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
python3使用logging包,如何把日志寫到系統(tǒng)的rsyslog中
這篇文章主要介紹了python3使用logging包,如何把日志寫到系統(tǒng)的rsyslog中的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Python 讀取有公式cell的結(jié)果內(nèi)容實(shí)例方法
在本篇文章里小編給大家整理的是關(guān)于Python 如何讀取有公式cell的結(jié)果內(nèi)容,需要的朋友們可以學(xué)習(xí)下。2020-02-02
Python并發(fā)爬蟲常用實(shí)現(xiàn)方法解析
這篇文章主要介紹了Python并發(fā)爬蟲常用實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
詳解利用django中間件django.middleware.csrf.CsrfViewMiddleware防止csrf
這篇文章主要介紹了詳解利用django中間件django.middleware.csrf.CsrfViewMiddleware防止csrf攻擊,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
python借助ChatGPT讀取.env實(shí)現(xiàn)文件配置隔離保障私有數(shù)據(jù)安全
這篇文章主要為大家介紹了python讀取.env實(shí)現(xiàn)文件配置隔離保障私有數(shù)據(jù)安全,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03

