pythonurlretrieve
❶ 如何用python做爬蟲
1)首先你要明白爬蟲怎樣工作。
想像你是一隻蜘蛛,現在你被放到了互聯「網」上。那麼,你需要把所有的網頁都看一遍。怎麼辦呢?沒問題呀,你就隨便從某個地方開始,比如說人民日報的首頁,這個叫initial pages,用$表示吧。
在人民日報的首頁,你看到那個頁面引向的各種鏈接。於是你很開心地從爬到了「國內新聞」那個頁面。太好了,這樣你就已經爬完了倆頁面(首頁和國內新聞)!暫且不用管爬下來的頁面怎麼處理的,你就想像你把這個頁面完完整整抄成了個html放到了你身上。
突然你發現, 在國內新聞這個頁面上,有一個鏈接鏈回「首頁」。作為一隻聰明的蜘蛛,你肯定知道你不用爬回去的吧,因為你已經看過了啊。所以,你需要用你的腦子,存下你已經看過的頁面地址。這樣,每次看到一個可能需要爬的新鏈接,你就先查查你腦子里是不是已經去過這個頁面地址。如果去過,那就別去了。
好的,理論上如果所有的頁面可以從initial page達到的話,那麼可以證明你一定可以爬完所有的網頁。
那麼在python里怎麼實現呢?
很簡單
import Queue
initial_page = "初始化頁"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直進行直到海枯石爛
if url_queue.size()>0:
current_url = url_queue.get() #拿出隊例中第一個的url
store(current_url) #把這個url代表的網頁存儲好
for next_url in extract_urls(current_url): #提取把這個url里鏈向的url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break
寫得已經很偽代碼了。
所有的爬蟲的backbone都在這里,下面分析一下為什麼爬蟲事實上是個非常復雜的東西——搜索引擎公司通常有一整個團隊來維護和開發。
2)效率
如果你直接加工一下上面的代碼直接運行的話,你需要一整年才能爬下整個豆瓣的內容。更別說Google這樣的搜索引擎需要爬下全網的內容了。
問題出在哪呢?需要爬的網頁實在太多太多了,而上面的代碼太慢太慢了。設想全網有N個網站,那麼分析一下判重的復雜度就是N*log(N),因為所有網頁要遍歷一次,而每次判重用set的話需要log(N)的復雜度。OK,OK,我知道python的set實現是hash——不過這樣還是太慢了,至少內存使用效率不高。
通常的判重做法是怎樣呢?Bloom Filter. 簡單講它仍然是一種hash的方法,但是它的特點是,它可以使用固定的內存(不隨url的數量而增長)以O(1)的效率判定url是否已經在set中。可惜天下沒有白吃的午餐,它的唯一問題在於,如果這個url不在set中,BF可以100%確定這個url沒有看過。但是如果這個url在set中,它會告訴你:這個url應該已經出現過,不過我有2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時候,可以變得很小很少。一個簡單的教程:Bloom Filters by Example
注意到這個特點,url如果被看過,那麼可能以小概率重復看一看(沒關系,多看看不會累死)。但是如果沒被看過,一定會被看一下(這個很重要,不然我們就要漏掉一些網頁了!)。 [IMPORTANT: 此段有問題,請暫時略過]
好,現在已經接近處理判重最快的方法了。另外一個瓶頸——你只有一台機器。不管你的帶寬有多大,只要你的機器下載網頁的速度是瓶頸的話,那麼你只有加快這個速度。用一台機子不夠的話——用很多台吧!當然,我們假設每台機子都已經進了最大的效率——使用多線程(python的話,多進程吧)。
3)集群化抓取
爬取豆瓣的時候,我總共用了100多台機器晝夜不停地運行了一個月。想像如果只用一台機子你就得運行100個月了...
那麼,假設你現在有100台機器可以用,怎麼用python實現一個分布式的爬取演算法呢?
我們把這100台中的99台運算能力較小的機器叫作slave,另外一台較大的機器叫作master,那麼回顧上面代碼中的url_queue,如果我們能把這個queue放到這台master機器上,所有的slave都可以通過網路跟master聯通,每當一個slave完成下載一個網頁,就向master請求一個新的網頁來抓取。而每次slave新抓到一個網頁,就把這個網頁上所有的鏈接送到master的queue里去。同樣,bloom filter也放到master上,但是現在master只發送確定沒有被訪問過的url給slave。Bloom Filter放到master的內存里,而被訪問過的url放到運行在master上的Redis里,這樣保證所有操作都是O(1)。(至少平攤是O(1),Redis的訪問效率見:LINSERT – Redis)
考慮如何用python實現:
在各台slave上裝好scrapy,那麼各台機子就變成了一台有抓取能力的slave,在master上裝好Redis和rq用作分布式隊列。
代碼於是寫成
#slave.py
current_url = request_from_master()
to_send = []
for next_url in extract_urls(current_url):
to_send.append(next_url)
store(current_url);
send_to_master(to_send)
#master.py
distributed_queue = DistributedQueue()
bf = BloomFilter()
initial_pages = "www.renmingribao.com"
while(True):
if request == 'GET':
if distributed_queue.size()>0:
send(distributed_queue.get())
else:
break
elif request == 'POST':
bf.put(request.url)
好的,其實你能想到,有人已經給你寫好了你需要的:darkrho/scrapy-redis · GitHub
4)展望及後處理
雖然上面用很多「簡單」,但是真正要實現一個商業規模可用的爬蟲並不是一件容易的事。上面的代碼用來爬一個整體的網站幾乎沒有太大的問題。
但是如果附加上你需要這些後續處理,比如
有效地存儲(資料庫應該怎樣安排)
有效地判重(這里指網頁判重,咱可不想把人民日報和抄襲它的大民日報都爬一遍)
有效地信息抽取(比如怎麼樣抽取出網頁上所有的地址抽取出來,「朝陽區奮進路中華道」),搜索引擎通常不需要存儲所有的信息,比如圖片我存來幹嘛...
及時更新(預測這個網頁多久會更新一次)
如你所想,這里每一個點都可以供很多研究者十數年的研究。雖然如此,
「路漫漫其修遠兮,吾將上下而求索」。
所以,不要問怎麼入門,直接上路就好了:)
❷ 如何設置python 中函數 urlretrieve 下載文檔,5秒沒有下載完成就跳出執行下一次的下載
給你一段代碼吧。
importsocket
socket.setdefaulttimeout(5.0)
importurllib
urllib.urlretrieve(url,filename)
通過socket類設置氏冊滲全局殲脊的超姿轎時。
❸ 怎麼使用python扒網上的照片
# coding=utf-8
# 聲明編碼方式 默認編碼方式ASCII
import urllib
import time
import re
import os
'''''
Python下載游迅網圖片 BY:Eastmount
'''
'''''
**************************************************
#第一步 遍歷獲取每頁對應主題的URL
**************************************************
'''
fileurl=open('yxdown_url.txt','w')
fileurl.write('****************獲取游訊網圖片URL*************\n\n')
#建議num=3 while num<=3一次遍歷一個頁面所有主題,下次換成num=4 while num<=4而不是1-75
num=3
while num<=3:
temp = ''+str(num)+'.html'
content = urllib.urlopen(temp).read()
open('yxdown_'+str(num)+'.html','w+').write(content)
print temp
fileurl.write('****************第'+str(num)+'頁*************\n\n')
#爬取對應主題的URL
#<div class="cbmiddle"></div>中<a target="_blank" href="/飢肢凳html/5533.html" >
count=1 #計算每頁1-75中具體網頁個數
res_div = r'<div class="cbmiddle">(.*?)</div>'
m_div = re.findall(res_div,content,re.S|re.M)
for line in m_div:
#fileurl.write(line+'\n')
#獲取每頁所有主題對應的URL並輸出
if "_blank" in line: #防止獲取列表list/1_0_1.html list/2_0_1.html
#獲取主題
fileurl.write('\n\n********************************************\n')
title_pat = r'<b class="imgname"爛旅>(.*?)</b>'
title_ex = re.compile(title_pat,re.M|re.S)
title_obj = re.search(title_ex, line)
title = title_obj.group()
print unicode(title,'utf-8')
fileurl.write(title+'\n')
#獲取URL
res_href = r'<a target="_blank" href="(.*?)"'
m_linklist = re.findall(res_href,line)
#print unicode(str(m_linklist),'utf-8')
for link in m_linklist:
fileurl.write(str(link)+'\n') #形如"/html/5533.html"
'''''
**************************************************
#第二步 去到具體圖像頁面 下載HTML頁面
#注意先本地創建yxdown 否則報錯No such file or directory
**************************************************
'''
#下載HTML網頁無原飢族圖 故加'#p=1'錯誤
#HTTP Error 400. The request URL is invalid.
html_url = ''+str(link)
print html_url
html_content = urllib.urlopen(html_url).read() #具體網站內容
#可注釋它 暫不下載靜態HTML
open('yxdown/yxdown_html'+str(count)+'.html','w+').write(html_content)
'''''
#第三步 去到圖片界面下載圖片
#點擊"查看原圖"HTML代碼如下
#<a href="javascript:;" style=""onclick="return false;">查看原圖</a>
#通過JavaScript實現 而且該界面存儲所有圖片鏈接<script></script>之間
'''
html_script = r'<script>(.*?)</script>'
m_script = re.findall(html_script,html_content,re.S|re.M)
for script in m_script:
res_original = r'"original":"(.*?)"' #原圖
m_original = re.findall(res_original,script)
for pic_url in m_original:
print pic_url
fileurl.write(str(pic_url)+'\n')
'''''
#第四步 下載圖片
#如果瀏覽器存在驗證信息如維基網路 需添加如下代碼
class AppURLopener(urllib.FancyURLopener):
version = "Mozilla/5.0"
urllib._urlopener = AppURLopener()
'''
filename = os.path.basename(pic_url) #去掉目錄路徑,返迴文件名
#No such file or directory 需要先創建文件Picture3
urllib.urlretrieve(pic_url, 'E:\\Picture3\\'+filename)
#IOError: [Errno socket error] [Errno 10060]
#只輸出一個URL 否則輸出兩個相同的URL
break
#當前頁具體內容個數加1
count=count+1
time.sleep(0.1)
else:
print 'no url about content'
time.sleep(1)
num=num+1
else:
print 'Download Over!!!'
❹ python 如何將大量圖片的url保存到本地
你如果要保存圖片的url,直接把imgsrc寫入本地文件就可以了,urllib.request.urlretrieve(imgsrc)這個的意思是你要保存的不是圖片的url,而是要把圖片下載下來,這個是要批量爬取網站上的圖片,需要考慮網站的反爬蟲措施了。
❺ python 3中urlretrieve方法直接將遠程數據下載到本地.為什麼不行
你的路徑可能不對,按照我的代碼,你需要在d盤根目錄下新建一個test文件夾,才能正常運行
❻ 按樓號保存圖片!用python怎麼實現
分類: 電腦/網路 >> 程迅森盯序設計 >> 其他編程語言
問題描述:
按樓號保存圖片!用python怎麼實現?
我要把k68上2128號任務所有的作品全部保存到硬碟上
比如三樓的作品是就命名為3(如果是gif格式存為3.gif)
四樓的作品存為4
如果同一樓有多個作品,比如39樓,第一個作品就命名為39-1
第二個就是39-2
以此類推。。。。
k68 2128號任務 連接:k68/PostViewMission?dMode=0&PostPage=1&BoardID=1001&imageID=34314&page=1&imageNum=1&SearchWords=&sstype=1&rmd=19260
解析:
這種情況用正則表達式最恰當。
注意:程序運行完畢後,note.txt 將記載所有程序找不到圖片鏈接的樓號及相關的頁春慎面鏈接,
你必須自己鑒定那些樓里是否真的沒有圖片。估計有少於十層其實是有圖片畝和的(鏈接太不規律所致): 你自己儲存好了。
# -*- coding: utf-8 -*-
import urllib, re, time
URLTemplate = 'k68/PostViewMission?dMode=0&PostPage=%d' + \
'&BoardID=1001&imageID=34314&page=1&imageNum=1&SearchWords=&sstype=1&rmd=19260'
pageURLs = [ URLTemplate % pageNum for pageNum in range( 1, 155 ) ]
startTime = time.time( )
noteFile = open( 'note.txt', 'w' )
savedFileCount = 0
print '\nInitializing... (will plete shortly)',
for pageURL in pageURLs :
pageSource = urllib.urlopen( pageURL ).read( )
splitted = re.split( '<b>(\d+)樓', pageSource )[ 1 : ]
for i in range( len( splitted ) ): # for each floor
if not i % 2: # floor numbers in even posistions, floor source in odd positions
floorNumber = splitted[ i ]
pictureURLPattern = r'(?<=href=")[^? ]+?\.\w{3}(?="\s*target)'
pictureURLs = re.findall( pictureURLPattern, splitted[ i + 1 ] )
if not pictureURLs:
note = 'no picture URL found at floor #%s on this page:\n%s\n' % ( floorNumber, pageURL )
print >> noteFile, note
else:
if len( pictureURLs ) == 1:
fileName = floorNumber + pictureURLs[ 0 ][ -4 : ]
urllib.urlretrieve( pictureURLs[ 0 ], fileName )
else:
for pictureNumber, pictureURL in enumerate( pictureURLs ):
fileName = '%s-%d%s' % ( floorNumber, pictureNumber + 1, pictureURL[ -4 : ] )
urllib.urlretrieve( pictureURL, fileName )
savedFileCount += len( pictureURLs )
print '\rSo far, %d files saved, floor # %s reached.\t\t\t\t' % ( savedFileCount, floorNumber ),
print '\n\nAll done! Saved %d files, took %.1f minutes.' % ( savedFileCount, ( time.time( ) - startTime ) / 60 )
❼ 請教如何用python下載文件到本地
知道文件的url地址就用urllib模塊的urlretrieve函數。urllib.urlretrieve(url,
filename)filename是要保存到本地的文件名。函數後面還有2個可選參數,要用就看幫助文檔吧。多線下載的話,每一線程要指定下載伺服器上文件的哪一塊。http協議中head里可以指定Range。下面用的是urllib2模塊request
=
urllib2.Request(url)request.add_header("Range",
"bytes=%d-%d"%(1024,
204)
#指定下載文件的范圍opener
=
urllib2.build_opener()data
=
opener.open(request).read()現在data裡面就是文件的1024位元組到2048位元組的內容。
❽ 如何用python把網頁上的文本內容保存下來
1、了解Python如何獲取網頁內容。
❾ 用python抓取的網頁保存後為什麼亂碼
從你給的代碼來是Python2。我下面給一個基於Python3的代碼,可以參考一下:
romurllib.requestimporturlopen;
fromurllib.parseimportquote;
rawtext=urlopen('http://www.ccnu.e.cn',timeout=15).read();
print(rawtext)
rawtext=rawtext.decode('gbk')
print(rawtext)
f=open('ccnu.txt','w',encoding='utf8');
f.write(rawtext)
大概的原理是,在Python3下面,抓取到的頁面默認是byte類型的(通過第4行輸出的結果就可以看出來),我們需要根據網頁的實際編碼進行處理。本例中給的網頁使用的是gb2312。所以,我要先以gbk的格式進行解碼(gbk包含了gb2312,能夠表示更多的漢語字元),解碼後實際上得到的就是unicode碼了,由於我的控制台編碼設置的是utf8,在列印時系統會自動將字元串從unicode轉為utf8,所以第6行控制台列印結果正常;第7行寫入文件時也要指定文件的編碼格式,我這里選擇的是utf8,當然用gbk也是一切正常的,因為這個編碼設置的是保存文件的編碼,而不是原來那個網頁內容的編碼了。字元串編碼和文件編碼不是一回事。打開ccnu.txt發現無亂碼。
Python2的代碼我不熟。
建議你也在代碼中添加print 看控制輸出是否正常。如果控制台輸出正常,則有可能是在保存頁面文件時,沒有正確指定內容字元串的encode格式。或者把所有gb2312換為gbk再試試。
反正Python2下面極容易出現漢字亂碼,如果能理解編碼encode和解碼decode的含義,了解Python2的字元串處理過程,就可以避免這些問題。
❿ 如何用Python抓取動態頁面信息
解決思路:
有一個思路最為簡單的思路可以動態解析頁面信息。urllib不可以解析動態信息,但是瀏覽器可以。在瀏覽器上展現處理的信息其實是處理好的HTML文
檔。這為我們抓取動態頁面信息提供了很好的思路。在Python中有一個很有名的圖形庫——PyQt。PyQt雖然是圖形庫,但是他裡面
QtWebkit。這個很實用。谷歌的Chrome和蘋果的Safari都是基於WebKit內核開發的,所以我們可以通過PyQt中得QtWebKit
把頁面中的信息讀取載入到HTML文檔中,再解析HTML文檔,從HTML文檔中提取我們想用得信息。
所需材料:
作者本人實用Mac OS X。應該在Windows和Linux平台也可以採用相同的辦法。
1、Qt4 library
Library,而不是Creator。Library在Mac的默認安裝路徑下,應該是/home/username/Developor/,不要改變Qt4的默認安裝路徑。否則可能安裝失敗。
官方網址:http://qt-project.org/downloads
2、SIP、PyQt4
這兩個軟體可以在在PyQt的官網找到。下載的是它的源碼。Mac和Linux需要自己編譯。
下載地址是:http://www.riverbankcomputing.co.uk/software/pyqt/download
在終端切換到文件解壓後的目錄中。
在終端中輸入
python configure.py
make
sudo make install
進行安裝編譯。
SIP和PyQt4兩個安裝方法相同。但是PyQt4依賴SIP。所以先安裝SIP再安裝PyQt4
1、2兩步完成之後,Python的PyQt4的模塊就安裝好了。在Python shell中輸入import PyQt4看看能不能找到PyQt4的模塊。
3、Spynner
spynner是一個QtWebKit的客戶端,它可以模擬瀏覽器,完成載入頁面、引發事件、填寫表單等操作。
這個模塊可以在Python的官網找到。
下載地址: https://pypi.python.org/pypi/spynner/2.5
解壓後,cd到安裝目錄,然後輸入sudo python configure.py install安裝該模塊。
這樣Spynner模塊就安裝完成了,在python shell中試試import spynner看看該模塊有沒有安裝完成。
Spynner的簡單使用
Spynner的功能十分強大,但是由於本人能力有限,就介紹一下如何顯示網頁的源碼吧。
#! /usr/bin/python
#-*-coding: utf-8 -*-
import spynner
browser = spynner.Browser()
#創建一個瀏覽器對象
browser.hide()
#打開瀏覽器,並隱藏。
browser.load("http://www..com")
#browser 類中有一個類方法load,可以用webkit載入你想載入的頁面信息。
#load(是你想要載入的網址的字元串形式)
print browser.html.encode("utf-8")
#browser 類中有一個成員是html,是頁面進過處理後的源碼的字元串.
#將其轉碼為UTF-8編碼
open("Test.html", 'w+').write(browser.html.encode("utf-8"))
#你也可以將它寫到文件中,用瀏覽器打開。
browser.close()
#關閉該瀏覽器
通過這個程序,就可以比較容易的顯示webkit處理的頁面HTML源碼了。
spynner應用
下面介紹一下spynner的簡單應用,通過簡單的程序,可以獲取你在瀏覽器中看到的頁面的全部圖片。用HTMLParser、BeautifulSoup等都可以完成HTMLParser文檔的解析。而我選擇HTMParser。
#!/usr/bin/python
import spynner
import HTMLParser
import os
import urllib
class MyParser(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == 'img':
url = dict(attrs)['src']
name = os.path.basename(dict(attrs)['src'])
if name.endswith('.jpg') or name.endswith('.png') or name.endswith('gif'):
print "Download.....", name
urllib.urlretrieve(url, name)
if __name__ == "__main__":
browser = spynner.Browser()
browser.show()
browser.load("http://www.artist.cn/snakewu1994/StyleBasis_Four/en_album_607236.shtml")
Parser = MyParser()
Parser.feed(browser.html)
print "Done"
browser.close()
通過這個程序,可以下載你在頁面上看到的全部圖片。簡單的幾行程序就完成了這個艱巨的任務。實現了圖片的批量處理。這真是Python語言的優勢,再艱巨的任務交給第三方吧。