這兩年python特別火,火到部落格園現在也是隔三差五的出現一些python的文章。各種開源軟體、各種爬蟲演算法紛紛開路,作為網際網路行業的IT狗自然看的我也是心癢癢,於是趁著這個霧霾橫行的週末瞅了兩眼,作為一名老司機覺得還是應該以練帶學,1024在程式設計師界這麼流行的網站,當然拿來先練一練。
python自稱是以自然語言的視角來程式設計,特點是開發快,語言簡潔,沒那麼多技巧,大名鼎鼎的豆瓣、youtube都是使用python開發的網站,看來python在大規模使用這個方面來講應該沒有啥子問題;python也不是沒有缺點在效能方面就Java、C++等老前輩還是沒得比的,另外python和nodejs一樣只能使用CPU單核,也是效能方面影響是因素之一。但python在特定領域表現突出,特別是指令碼、爬蟲、科學演算法等。
好了,還是說正事如何爬取1024網站的圖片
分析
列表頁面
首先進入1024的導航網站,隨便點選一個地址進入選擇圖片區或者在網站地址後面新增thread0806.php?fid=16&search=&page=
,這就是1024網站的圖片區,這個爬蟲就是主要抓取這個區域的所有圖片,使用瀏覽器debug分析一下這個頁面發現基本都是列表頁,格式如下:
在位址列http://xxxxxx.biz/thread0806.php?fid=16&search=&page=
後面拼1、2、3等於就是訪問圖片區第一頁、第二頁、第三頁的列表頁。根據這些列表頁就可以爬出具體的每一個圖片頁的地址,類似上圖的地址:htm_data/16/1611/2114702.html
在地址的前面拼接上主站地址就是具體的圖片頁了。所以根據以上的分析:通過迴圈位址列找到不同的列表頁在根據列表頁找到具體的圖片頁
位址列->圖片列表->圖片頁地址
獲取列表頁圖片地址程式碼如下:
import urllib.request,socket,re,sys,os
baseUrl='http://xxxx.biz/'
def getContant(Weburl):
Webheader= {'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.103 Safari/537.36',}
req = urllib.request.Request(url = Weburl,headers=Webheader)
respose = urllib.request.urlopen(req)
_contant = respose.read()
respose.close()
return str(_contant)
def getUrl(URL):
pageIndex = 1
for i in range(1,int(pageIndex)+1):
Weburl = URL + str(i)
contant = getContant(Weburl)
comp = re.compile(r'<a href="htm_data.{0,30}html" target="_blank" id=""><font color=g')
urlList1 = comp.findall(contant)
comp = re.compile(r'a href="(.*?)"')
urlList2 = comp.findall(str(urlList1))
urlList = []
for url1 in urlList2:
url2 = baseUrl+url1
urlList.append(url2)
return urlList
URL = baseUrl+'thread0806.php?fid=16&search=&page='
UrlList = getUrl(URL)
print(UrlList)
在這個地址後面拼接1到N就是不同的列表頁
圖片頁面
利用瀏覽器debug一下頁面,圖片基本上都是外鏈地址,以http或者https開頭以jpg、png、gif結尾,寫個正規表示式匹配這些地址,然後交給程式下載就OK了。
頁面程式碼如下:
在下載過程中遇到了幾個問題,就是有的頁面會報403禁止訪問等,應該是網站加了一些防止爬蟲的手段,網上找了下加上header引數來模擬瀏覽器訪問就解決了;
下載單個頁面程式碼如下:
import urllib.request,socket,re,sys,os
#定義檔案儲存路徑
targetPath = "D:\\temp\\1024\\1"
def openUrl(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/51.0.2704.63 Safari/537.36'
}
req = urllib.request.Request(url=url, headers=headers)
res = urllib.request.urlopen(req)
data = res.read()
downImg(data)
def downImg(data):
for link,t in set(re.findall(r'([http|https]:[^\s]*?(jpg|png|gif))', str(data))):
if link.startswith('s'):
link='http'+link
else:
link='htt'+link
print(link)
try:
opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(link,saveFile(link))
except:
print('失敗')
def saveFile(path):
#檢測當前路徑的有效性
if not os.path.isdir(targetPath):
os.mkdir(targetPath)
#設定每個圖片的路徑
pos = path.rindex('/')
t = os.path.join(targetPath,path[pos+1:])
return t
url = "http://xxxx.biz/htm_data/16/1611/2115193.html"
openUrl(url)
批量爬取
批量爬取有兩個工作要做,第一for迴圈目標內的所有列表頁,第二為了避免重複爬取,需要給每個頁面建立唯一的資料夾,下次爬取的時候如果存在直接跳過。最後在理一下所有的爬取步驟:
迴圈位址列->找出圖片頁列表->圖片頁分析找出圖片地址->為圖片頁建立唯一的資料夾->開始下載頁面圖片
完整的程式碼如下:
import urllib.request,socket,re,sys,os
baseUrl='http://xxxx.biz/'
targetPath = "D:\\temp\\1024\\"
def getContant(Weburl):
Webheader= {'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.103 Safari/537.36',}
req = urllib.request.Request(url = Weburl,headers=Webheader)
respose = urllib.request.urlopen(req)
_contant = respose.read()
respose.close()
return str(_contant)
def getUrl(URL):
pageIndex = 1
for i in range(1,int(pageIndex)+1):
Weburl = URL + str(i)
contant = getContant(Weburl)
comp = re.compile(r'<a href="htm_data.{0,30}html" target="_blank" id=""><font color=g')
urlList1 = comp.findall(contant)
comp = re.compile(r'a href="(.*?)"')
urlList2 = comp.findall(str(urlList1))
urlList = []
for url1 in urlList2:
url2 = baseUrl+url1
urlList.append(url2)
return urlList
def openUrl(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/51.0.2704.63 Safari/537.36'
}
filePath=targetPath+url[-12:-5]
#檢測當前路徑的有效性
if not os.path.isdir(filePath):
os.mkdir(filePath)
req = urllib.request.Request(url=url, headers=headers)
res = urllib.request.urlopen(req)
data = res.read()
downImg(data,filePath)
else:
print("已經下載過的地址跳過:"+url)
print("filePath "+filePath)
def downImg(data,filePath):
for link,t in set(re.findall(r'([http|https]:[^\s]*?(jpg|png|gif))', str(data))):
if link.startswith('s'):
link='http'+link
else:
link='htt'+link
print(link)
try:
opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(link,saveFile(link,filePath))
except:
print('失敗')
def saveFile(path,filePath):
#設定每個圖片的路徑
pos = path.rindex('/')
t = os.path.join(filePath,path[pos+1:])
return t
def openPage(UrlList):
for pageUlr in UrlList:
try:
print('正在下載地址:'+pageUlr)
openUrl(pageUlr)
except:
print('地址:'+pageUlr+'下載失敗')
URL = baseUrl+'thread0806.php?fid=16&search=&page='
for num in range(0,20):#0-20頁
print("#######################################")
print("##########總目錄下載地址###############")
print(URL+str(num))
print("#######################################")
print("#######################################")
UrlList = getUrl(URL+str(num))
openPage(UrlList)
最後的爬取結果:
原始碼地址:python-crawler
具體地址和原始碼在一起
其它
關於python2和python3的爭論,網站爭論比較大python3不相容pyhton2,很多第三方的類庫暫時還沒有支援python3等等,但是對於我們新手來說,肯定是往前看果斷python3.
程式碼比較冗餘幾個地方還沒有寫好,還在慢慢學習中,目前只是搞的可以跑起來。還有幾個問題沒有解決,下載一段時間後會莫名其妙的斷掉目前還麼找到原因,後期看是否可以加上多執行緒來爬取可能會快一點,大家有什麼更好的建議也可以提出來。
參考:
作者:純潔的微笑
出處:http://www.ityouknow.com/
版權所有,歡迎保留原文連結進行轉載:)