python學習筆記(一)
阿新 • • 發佈:2017-07-04
href ons xxx 自動下載 fail 響應 cdn pat pda
因為工作需要,經常需要到新浪某博客去找資料,在博文目錄裏一頁頁地肉眼搜索,看到合適的標題再點擊開鏈接查看內容,知道合適地再復制下來。很煩人。於是一直有個想法,學會爬蟲。
拿著單位發的購書卡去買了本入門的書《python編程從入門到實踐》,憑著一點編程的底子,三個小時看完了基礎部分,然後安裝python就開始搜集各種網絡文字教程,開始實踐。
(一)正則標題式提取博文文字
新浪博客博文一句話可以放在幾個標簽裏面,感覺很奇葩(也許就是我無知)。因為亂七八糟的緣故,sir學習了一下re正則表達式模塊,然後開始動手
#導入request方法 from urllib import request #導入正則表達式模塊 import re #打開網頁,獲取響應文本 response=request.urlopen(‘http://blog.sina.com.cn/s/blog_xxxxxxx.html‘) #讀取網頁源碼 不知道怎麽表達這個東西 page=response.read() #轉碼 js= page.decode(‘utf-8‘) #編譯匹配模式 pat=re.compile(r‘((?<=>)[^>]+?(?=</FONT>)|(?<=>)[^>]+?(?=</SPAN>))‘) #匹配網頁內容 match=re.findall(pat,js) #若匹配則輸出 if match: n=0 for each_match in match: n+=1 print(n," : "+each_match +‘\n‘)
正則匹配模式寫得不夠完美把極少數的無關的內容匹配出來,加上各種網絡教程各種的看不懂,使得sir失去了努力的方向。
(二)根據Excel中的Url下載圖片
時隔一個月,突然有了采集圖片的機會,又讓sir有了一點動力。因為URL已經通過其他爬蟲采集到excel工作簿當中,於是sir又學習了一下第三方包openpyxl,之後又開始動手了。
from urllib import request #導入request函數 from openpyxl import load_workbook #導入load_workbook函數 #自定義一個根據url和圖片文件名稱為參數,自動下載圖片的函數 def downloadImage(imageUrl,imagePath): response=request.urlopen(imageUrl)#訪問圖片地址,獲得響應 imageContents=response.read()#獲取圖片內容 f=open(imagePath,‘wb‘)#打開文件 f.write(imageContents)#寫入內容 f.close#關閉文件 #打開Excel workbook wb=load_workbook(‘image.xlsx‘) #指定工作表 ws=wb.active
#獲取單元格內容 從第二行開始 到空白單元格結束 i=2 while ws.cell(row=i,column=1).value!=None: #生成文件名 A列為文件名稱 Path= str(i-1)+‘_‘+ws.cell(row=i,column=1).value +‘.jpg‘ #獲取URL地址 B列為URL地址 Url=ws.cell(row=i,column=2).value #調用函數下載圖片 downloadImage(imageUrl=Url,imagePath=Path) #循環下載圖片 print(‘已下載第‘+str(i-1)+‘張高清圖片>>>‘) i+=1
因為函數downloadimage內部沒有添加異常處理,於是碰到request失敗的時候,腳本就停止不動了。添加了異常處理之後,sir有發覺下載的速度真的好慢。於是第二天求助了一位相識。
(三)多線程下載圖片
這位朋友發了一段代碼,讓我自己學習。研究之後sir發現了,把具體要做的事情,放到多線程下載那個類的內部,就可以使用多線程下載。速度立馬快的飛起。30秒給我下了2000多張圖片,高達1G,還好我及時終止了腳本。
同時Sir也學到異常處理怎麽寫,就是在json中找到圖片地址那個寫法一開始令人費解,花了一段時間才明白怎麽回事。
import requests import json import threading Default_Header = { #具體請求頭自己去弄 } _session=requests.session() _session.headers.update(Default_Header) #多線程下載 class myThread(threading.Thread): def __init__(self,imgUrl,fname): threading.Thread.__init__(self) self.imgUrl=imgUrl self.fname=fname def run(self): print("downloading",self.imgUrl) download(self.imgUrl,self.fname) def download(fileid,type): img_url="http://img.hb.aicdn.com/"+fileid imgresp=requests.get(img_url) byte_img = imgresp.content try: out = open(type, ‘wb‘) out.write(byte_img) out.flush() out.close() except Exception as e: print(e) if __name__ == "__main__": r =_session.get(‘http://huaban.com/pins/873774526/?xxxxxx‘) url=json.loads(r.text) urlList=url[‘pin‘][‘board‘][‘pins‘] for i in urlList: key=i[‘file‘][‘key‘] print(key) #download(key,key+‘.jpg‘) myThread(key,key+‘.jpg‘).start()
(四)多線程采集改造
from urllib import request from bs4 import BeautifulSoup from openpyxl import Workbook import threading import re import time #功能函數 def get_title(url): global n #變量全局化 global pageindex #變量全局化 #global ws #為什麽聲明與不聲明都一樣? try: #打開網頁,保存試卷標題和鏈接 r=request.urlopen(url,timeout=10) #打開網頁,設置超時 response s=r.read() #讀取網頁源碼 js=s.decode(‘utf-8‘) #網頁轉碼 soup=BeautifulSoup(js,‘lxml‘) #網頁解析 #正則查找子節點 for a in soup.find_all(‘a‘,href=re.compile(r‘http://blog.sina.com.cn/s/blog‘)): n+=1 #計數 ws.cell(row=n+1,column=1).value=n #寫入序號 ws.cell(row=n+1,column=2).value=a.string #寫入標題 ws.cell(row=n+1,column=3).value=a.get(‘href‘) #寫入鏈接 print("download succeed >>>>"+url+‘\n‘) #正常輸出 except Exception as e: print("download failed >>>>"+url+‘\n‘) #異常輸出 if __name__ ==‘__main__‘:#主線程 start=time.time() #開始時間 filename=‘多線程爬取啟迪慧想試題標題與鏈接.xlsx‘ #Excel文件名 threads=[] #新建線程列表 wb=Workbook() #新建工作簿 ws=wb.active #活動工作表 n=0 #初始化計數 #輸入表頭 ws.cell(row=n+1,column=1).value=‘序號‘ ws.cell(row=n+1,column=2).value=‘標題‘ ws.cell(row=n+1,column=3).value=‘鏈接‘ #設置起止頁碼 pageindex=1 pagecount=10 #filename=str(pagecount)+filename while pageindex<=pagecount: url=u‘http://blog.sina.com.cn/s/articlelist_xxxxxxxxx_0_‘+str(pageindex)+‘.html‘ t=threading.Thread(target=get_title,args=(url,))#添加子線程 threads.append(t) #加入線程列表 pageindex+=1 #下一頁 for t in threads: t.setDaemon(True) #守護線程 必須在start()之前 t.start() #開始線程 #若t.join()放此處 則變成單線程 for t in threads: t.join() #線程等待 主線程必須在子線程執行結束之後 才能繼續 wb.save(filename=filename) #保存工作簿 end=time.time() #結束時間 print(‘Usedtime %f seconds!‘ % (end-start) +‘\n‘) #輸出耗時!
python學習筆記(一)