###### tags: `web crawler`,`網路爬蟲`,`圖片抓取` # web crawler 實作--PTT圖片抓取(Beauty版) **一次把美圖抓下來** PTT網址、標題、抓取日期、文章連結、作者、圖片連結 PTT Beauty版 <https://www.ptt.cc/bbs/Beauty/index.html> :bulb:**先解析網頁** **擷取標題"r-ent"** ![](https://i.imgur.com/kqnIv8J.jpg) **擷取標題與連結** 注意連結只有部分,需自行補上前面的完整網址(https://www.ptt.cc) ![](https://i.imgur.com/CSmaCBC.jpg) **擷取日期** ![](https://i.imgur.com/DeYNIbe.jpg) **擷取作者** ![](https://i.imgur.com/IjDr4HK.jpg) **存取圖片** ![](https://i.imgur.com/pxsQHn7.jpg) ```python= def _savePic(imgurl,title): #傳入圖片文章連結網址與文章標題 rqimg=requests.get(imgurl,cookies=mycookies).text #模擬送出cookies的驗證值 rq2img=BeautifulSoup(rqimg,"html5lib") try: os.makedirs(title) #以文章標題為名稱建立一個子目錄用來存放文章內的圖片 except FileExistsError: #若目錄已存在則顯示目錄已經存在的訊息 print("目錄已經存在!!!") print("---------------------------------------------") for imgitem in rq2img.find(id="main-content").find_all("a"): try: fullpath=imgitem["href"] #因為imgur.com對於圖片網址的定義較為寬鬆,所以我們必須先處理成正確的網址結構[https://i.imgur.com/xxxxxx.jpg] if fullpath.split("//")[1].startswith("m."): #把[m.]改成[i.] fullpath=fullpath.replace("//m.","//i.") if not fullpath.endswith(".jpg"): #把沒有[.jpg]的加上[.jpg] fullpath=fullpath+".jpg" print(fullpath) img_name=fullpath.split("/")[-1] if os.path.isfile(title+"\\"+img_name): #判斷圖片檔案是否已經存在,若不存在才做存檔的動作 print("檔案已經存在!!!") else: # print(title+"\\"+img_name) urllib.request.urlretrieve(fullpath,title+"\\"+img_name) #圖片存檔 except: continue def _getArticles(): #傳入的網址存放在[urL] global announce #在函式(區域)內,要更改全域變數的值,必須先宣告其為[global] rq1=requests.get(ptturl,cookies=mycookies).text #模擬送出cookies的驗證值 rq2=BeautifulSoup(rq1,"html5lib") #解析網頁 for items in rq2.find_all("div","r-ent"): if items.find("div","date").text != today: #判斷文章日期是否不是今日 announce = announce - 1 #不是的話就把[announce]減一,PTT有很多公告標題,此為把公告排除用 if announce==0: #[announce]為零時,傳回[None] return None else: try: print("====================================================") #我是分隔線 print("日期: ",items.find("div","date").text) #擷取文章發佈日期 print(items.find("div","title").text.strip()) #擷取文章標題 print("https://www.ptt.cc"+items.find("div","title").a["href"])#文章網址 print("作者: ",items.find("div","author").text) #文章作者 imgurl="https://www.ptt.cc"+items.find("div","title").a["href"] #此網址為後續存取圖片所用 title=items.find("div","title").text.strip() #標題 _savePic(imgurl,title) #用上面擷取的網址跟標題來存取圖片(自訂函式,用來圖片存檔) except: continue nexturl="https://www.ptt.cc"+rq2.find("div","btn-group btn-group-paging").find_all("a")[1]["href"] return nexturl #傳回[上頁]文章的網址,再度回傳到_getArticles(nexturl),就能重複一直抓到announce為0,停止 import requests from bs4 import BeautifulSoup import datetime #載入[datetime]模組,協助處理日期問題 import os #建立新資料夾與其他目錄相關的處理 import urllib #存檔用 ptturl="https://www.ptt.cc/bbs/Beauty/index.html" #PTT Beauty板 mycookies={"over18":"1"} #處理日期問題 today1=datetime.date.today() #載入時間 today2=str(today1).split("-") #today2是一個串列(list) if int(today2[1]) < 10: #月份若為單位數,前面會有一個空格 today=" "+str(int(today2[1]))+"/"+today2[2] else: today=today2[1]+"/"+today2[2] try: #先判斷目錄是否存在,若不存在才建立新目錄 os.makedirs(str(today1)) except FileExistsError: print("目錄已經存在!!!") newDir=str(today1)+"/" os.chdir(newDir) #切換到新建的目錄底下(不切換會建到與程式碼同一層) announce=50 #<判斷PTT上公告文章使用>非在函式內宣告,所以是[全域]變數 while ptturl: #使用條件式迴圈來處理下一頁資料的問題,只要[ptturl]不為空值就繼續抓下一頁的資料 ptturl=_getArticles() #[_getArticles()]是我們的自訂函式,用來處理網頁資料抓取 print("") print("**************************************") print("今天是: ",today1) print("圖片存放的目錄在: ",os.getcwd()) #顯示當前的目錄路徑 print("======================================") print(os.listdir()) #顯示出此目錄下的所有子目錄名稱 print("**************************************") ``` **結果** ![](https://i.imgur.com/gubkXYX.jpg) ![](https://i.imgur.com/2TCirwn.jpg)