本次過程僅供學習參考,請遵守相關法律法規。 首先我們分析網站:https://www.mzitu.com/all/ 不難發現,這個頁面上包含了大量的圖片鏈接,可以說是特別方便我們爬取圖片的,這是件好事。那麼我們繼續分析 這是第一頁的地址 這是第二頁的,所以我們爬取的時候只需要在鏈接後面增加“/num ...
本次過程僅供學習參考,請遵守相關法律法規。
首先我們分析網站:https://www.mzitu.com/all/
不難發現,這個頁面上包含了大量的圖片鏈接,可以說是特別方便我們爬取圖片的,這是件好事。那麼我們繼續分析
這是第一頁的地址
這是第二頁的,所以我們爬取的時候只需要在鏈接後面增加“/num”即可
那麼我們先來爬取首頁的內容
import requests import re #爬取首頁 url = 'https://www.mzitu.com/all/' header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0' } response = requests.get(url, headers = header).text print(response)
我們可以得到以下
ok 接下來我們需要從中提取我們想要的鏈接
#使用正則表達式提取需要的鏈接
req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:
print(url,pic_name)
這樣我們就獲得了我們需要的鏈接了
那麼接來下我們需要知道的是每個鏈接裡面到底有多少頁呢
我們進一步分析網頁觀察頁面源碼我們可以發現
我們可以從頁面中提取到最後一頁的內容
req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>' urls = re.findall(req,response) for url,pic_name in urls: print(url,pic_name) #獲取每個url內的總頁面數目 html = requests.get(url, headers=header).text req_last = "<a href='.*?'><span>«上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁»</span></a> </div>" last_num = re.findall(req_last,html) print(last_num) exit()
我們使用正則將所需要的最後一頁的頁碼提取出來即可獲得結果
那麼接下來就是拼接url了
我們嘗試在原本的第一頁的url後添加“/1”發現也可以進入我們需要的頁面這大大降低了代碼量
#將列表轉化為int for k in last_num: k=k k = int(k) #拼接url for i in range(1,k): url_pic = url + '/' + str(i) print(url_pic) exit()
ps:這裡的“exit()”是為了方便測試程式只要獲得一個主url下的地址即可 後面將會刪去
我們可以得到下麵的鏈接
這些鏈接打開都是有效的但是我們打開的並不直接是圖片的url
所以我們還要進一步對信息進行篩選,再優化一下代碼
#將列表轉化為int for k in last_num: k=k k = int(k) #拼接url for i in range(1,k): url_pic = url + '/' + str(i) headerss = { 'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"', 'Referer': url_pic, 'Host': 'www.mzitu.com' } html_pic_last = requests.get(url_pic, headers=headerss).text req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>' req_pic_url = re.findall(req_last_pic,html_pic_last) for link in req_pic_url: link = link links = str(link) print(links) image_content = requests.get(links, headerss).content print(image_content) # with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f: # f.write(image_content) exit()
可是經過測試,發現保存下來的圖片無法打開,檢查發現再最後一步下載圖片的時候發生了403錯誤:伺服器拒絕訪問
我試著換了herder可是還是不行,所以GG了!
附上目前為止全部源碼
import requests import re #爬取首頁 url_head = 'https://www.mzitu.com/all/' header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Referer' :'https://www.mzitu.com' } response = requests.get(url_head, headers = header).text #使用正則表達式提取需要的鏈接 req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>' urls = re.findall(req,response) for url,pic_name in urls: #獲取每個url內的總頁面數目 html = requests.get(url, headers=header).text req_last = "<a href='.*?'><span>«上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁»</span></a> </div>" last_num = re.findall(req_last,html) #將列表轉化為int for k in last_num: k=k k = int(k) #拼接url for i in range(1,k): url_pic = url + '/' + str(i) headerss = { 'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"', 'Referer': url_pic, } html_pic_last = requests.get(url_pic, headers=headerss).text req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>' req_pic_url = re.findall(req_last_pic,html_pic_last) for link in req_pic_url: link = link links = str(link) print(links) image_content = requests.get(links, headerss).content print(image_content) # with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f: # f.write(image_content) exit() exit()
分析了一下我的代碼 發現
這裡的headers沒有給出定義,可能因為這個出現了bug 我修改了一下
image_content = requests.get(links, headers = headerss).content
這樣測試一下
我們成功了!
完善代碼
import requests import re #爬取首頁 url_head = 'https://www.mzitu.com/all/' header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Referer' :'https://www.mzitu.com' } response = requests.get(url_head, headers = header).text #使用正則表達式提取需要的鏈接 req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>' urls = re.findall(req,response) for url,pic_name in urls: #獲取每個url內的總頁面數目 html = requests.get(url, headers=header).text req_last = "<a href='.*?'><span>«上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁»</span></a> </div>" last_num = re.findall(req_last,html) #將列表轉化為int for k in last_num: k=k k = int(k) #拼接url for i in range(1,k): url_pic = url + '/' + str(i) headerss = { 'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"', 'Referer': url_pic } html_pic_last = requests.get(url_pic, headers=headerss).text req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>' req_pic_url = re.findall(req_last_pic,html_pic_last) for link in req_pic_url: link = link links = str(link) print(links) image_content = requests.get(links, headers = headerss).content #保存圖片 with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f: f.write(image_content)
增加一點用戶體驗後的代碼
import requests import re #爬取首頁 sum = 0 url_head = 'https://www.mzitu.com/all/' header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Referer' :'https://www.mzitu.com' } response = requests.get(url_head, headers = header).text #使用正則表達式提取需要的鏈接 req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>' urls = re.findall(req,response) for url,pic_name in urls: #獲取每個url內的總頁面數目 html = requests.get(url, headers=header).text req_last = "<a href='.*?'><span>«上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁»</span></a> </div>" last_num = re.findall(req_last,html) #將列表轉化為int for k in last_num: k=k k = int(k) #拼接url for i in range(1,k): url_pic = url + '/' + str(i) headerss = { 'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"', 'Referer': url_pic } html_pic_last = requests.get(url_pic, headers=headerss).text req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>' req_pic_url = re.findall(req_last_pic,html_pic_last) for link in req_pic_url: link = link links = str(link) print('成功下載地址'+links+"的圖片") sum = sum +1 image_content = requests.get(links, headers = headerss).content #保存圖片 with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f: f.write(image_content) print("一共下載了"+str(sum)+"張圖片")
讓我們來看看最後的成果吧
本文由作者親自撰寫,如有不足各位大佬提出來,如需轉載請標明出處,謝謝