斗图高手教你用Python批量爬取表情包
前言
昨天跟小伙伴斗圖,關(guān)于斗圖這件事,我表示我從來沒有輸過。至于為什么不會輸,這些都是男人的秘密,今天我想把這個小技
巧告訴大家。學(xué)會了記得挑戰(zhàn)你最好的朋友,打賭讓他輸了請你吃大西瓜…
1、介紹
?平臺:斗圖啦
?語言:python
?技術(shù):python多線程、python安全隊列、python之Xpath、正則、request
以上我們使用的技術(shù),都是之前整理過的對不對,那么我們就根據(jù)之前的學(xué)習(xí)內(nèi)容來進行爬取斗圖表情包吧。
2、python爬取流程梳理
我們剛開始學(xué)習(xí)的時候,是不是每次都需要梳理下爬取的流程呢,那么這次咱們還是和之前一樣,首先我們需要找到我們爬取的平臺的網(wǎng)址是什么:
https://dou.yuanmazg.com/doutu?page=1
訪問這個界面之后,我們可以看到如下顯示的內(nèi)容:
然后我們往下滑之后,可以看到這里一共有1500+的頁面,那么我們現(xiàn)在爬取前50頁的內(nèi)容吧,大概流程我覺得應(yīng)該如下哈:
1.獲取每個頁面的url;2.將獲取到的url放置Queue中;3.從Queue中獲取一個Url,使用requests獲取內(nèi)容,使用xpath獲取取該Url中每一個圖片的Url;4.然后將每個圖片中的Url放入到另一個Queue中;5.然后再從第二個Queue中獲取圖片的url;6.根據(jù)Queue來下載并保存即可;7.以上步驟我們使用多線程+Queue的形式來進行。3、python爬取圖片
3.1 框架
老樣子,首先我們簡簡單單寫一個框架;
import threadingclass Producter(threading.Thread):passclass Consumer(threading.Thread):passdef main():passif __name__ == '__main__':main()然后我們一步一步進行;
3.2 初步獲取頁面有效信息
python學(xué)習(xí)交流Q群:906715085### import requests from lxml import etreeUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]')[0] Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') print(Page_div)3.3 提取每一個圖片的url和name import requests from lxml import etreeUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]//a//img') # Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') # print(Page_div) for i in Page_div:# print(etree.tostring(i, pretty_print=True, method='html').decode('utf-8'))Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Page_name = i.xpath("@alt")[0]print(Page_url)print(Page_name)輸出結(jié)果如下:
3.4 優(yōu)化名字
我們可以看到我們獲取的圖片的名字中有特殊符號,但是我們的電腦上文件名字是不可以出現(xiàn)特殊符號的,那么我們是不是就需
要把名字給他處理一下呢,優(yōu)化走起,優(yōu)化之后的代碼如下:
import requests from lxml import etree import reUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]//a//img') # Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') # print(Page_div) for i in Page_div:# print(etree.tostring(i, pretty_print=True, method='html').decode('utf-8'))Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Page_name = i.xpath("@alt")[0]Page_name = re.sub(r'[,。??,/\\·\*\ ]', '', Page_name)print(Page_url)print(Page_name)隨之我們又發(fā)現(xiàn)了另一個問題,那就是有些圖片他是沒有添加描述的,也就是無法獲取該圖片的名字,那么我們就隨機給他一個
名字吧;
import requests from lxml import etree import re import randomUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]//a//img') # Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') # print(Page_div) for i in Page_div:# print(etree.tostring(i, pretty_print=True, method='html').decode('utf-8'))Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Page_name = i.xpath("@alt")[0]Page_name = re.sub(r'[,。??,/\\·\*\ ]', '', Page_name)if Page_name == "":Page_name = str(random.random())print(Page_url)print(Page_name)到這里是不是名字這個事兒就完事兒了呢,當(dāng)然不了,想一下,我們在電腦上創(chuàng)建文件的時候是不是還需要后綴名呢,那我們就
應(yīng)該也把后綴名獲取一下子,再次優(yōu)化之后,代碼如下:
import requests from lxml import etree import re import random import osUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]//a//img') # Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') # print(Page_div) for i in Page_div:# print(etree.tostring(i, pretty_print=True, method='html').decode('utf-8'))Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Suffix = os.path.splitext(Page_url)[1]Page_name = i.xpath("@alt")[0]Page_name = re.sub(r'[,。??,/\\·\*\ ]', '', Page_name)if Page_name == "":Page_name = str(random.random()) + Suffixelse:Page_name = Page_name + Suffixprint(Page_url)print(Page_name)運行之后結(jié)果如下:
好的,這樣子的話我們就成功的使用python獲取了每一個頁面中每一個圖片的地址和名字
3.5 下載
當(dāng)我們獲取到了圖片的下載地址,以及圖片名字之后,我們就可以進行下載了,那么我們的代碼就變成了下面的內(nèi)容:
python學(xué)習(xí)交流Q群:906715085#### import requests from lxml import etree import re import random import os from urllib import requestUrl = 'https://dou.yuanmazg.com/doutu?page=1' Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'} Page_get = requests.get(url=Url, headers=Header) Page_content = Page_get.text Page_message = etree.HTML(Page_content) Page_div = Page_message.xpath('//div[@class="page-content"]//a//img') # Page_div = etree.tostring(Page_div, pretty_print=True, method='html').decode('utf-8') # print(Page_div) for i in Page_div:# print(etree.tostring(i, pretty_print=True, method='html').decode('utf-8'))Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Suffix = os.path.splitext(Page_url)[1]Page_name = i.xpath("@alt")[0]Page_name = re.sub(r'[,。??,/\\·\*\ ]', '', Page_name)if Page_name == "":Page_name = str(random.random()) + Suffixelse:Page_name = Page_name + Suffix# print(Page_url)# print(Page_name)request.urlretrieve(Page_url, 'doutula/' + Page_name)print("{}下載完成了~~~".format(Page_name))運行之后會輸出哪個下載完成了,如下:
我不想做個膚淺的人.jpg下載完成了~~~
我黑點沒事你別綠了.jpg下載完成了~~~
我不想白活一輩子.jpg下載完成了~~~
我媽肚子里有墨水.jpg下載完成了~~~
勞資之前白的后來帥炸了炸黑了.jpg下載完成了~~~
我為了暗中保護你.jpg下載完成了~~~
我曬你家太陽了.jpg下載完成了~~~
黑夜給了我一雙黑色的眼睛可我卻一不小心按了全選!.jpg下載完成了~~~
— 省略部分內(nèi)容—
而且會在doutula這個文件夾下將下載的文件進行保存,如下圖:
3.6 添加安全隊列和多線程
為什么要使用多線程和安全隊列都清楚吧,就是為了速度和數(shù)據(jù)的準(zhǔn)確性啊。
既然我們實現(xiàn)了一個頁面中的表情包下載,那么我們是不是只需要稍微改動一下,多啟動幾個線程,添加幾個循環(huán),就能搞定了
呢,經(jīng)過我們的代碼優(yōu)化之后,成了下面的樣子:
python學(xué)習(xí)交流Q群:906715085#### import requests from lxml import etree import re import random import os from urllib import request from queue import Queue import threading import timeclass Producer(threading.Thread):Header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}def __init__(self, Page_queue, Photo_queue, *args, **kwargs):super(Producer, self).__init__(*args, **kwargs)self.Page_queue = Page_queueself.Photo_queue = Photo_queuedef run(self):while True:if self.Page_queue.empty():breakurl = self.Page_queue.get()self.photo_down(url)def photo_down(self, url):Page_get = requests.get(url=url, headers=self.Header)Page_content = Page_get.textPage_message = etree.HTML(Page_content)Page_div = Page_message.xpath('//div[@class="page-content"]//a//img')for i in Page_div:Page_url = 'https://dou.yuanmazg.com' + i.xpath("@data-original")[0]Suffix = os.path.splitext(Page_url)[1]Page_name = i.xpath("@alt")[0]Page_name = re.sub(r'[,。??,/\\·\*\ ]', '', Page_name)if Page_name == "":Page_name = str(random.random()) + Suffixelse:Page_name = Page_name + Suffixself.Photo_queue.put((Page_url, 'doutula/' + Page_name))class Consumer(threading.Thread):def __init__(self, Page_queue, Photo_queue, *args, **kwargs):super(Consumer, self).__init__(*args, **kwargs)self.Page_queue = Page_queueself.Photo_queue = Photo_queuedef run(self):while True:if self.Page_queue.empty() is True and self.Photo_queue.empty() is True:breakelse:img_url, img_name = self.Photo_queue.get()print(img_url)print(img_name)request.urlretrieve(img_url, img_name)def main():Page_queue = Queue(maxsize=100)Photo_queue = Queue(maxsize=2000)for i in range(1, 51): # 下載的頁數(shù)Page_url = 'https://dou.yuanmazg.com/doutu?page={}'.format(i)Page_queue.put(Page_url)for i in range(5): # 啟動5個消費者t1 = Producer(Page_queue, Photo_queue)t1.start()time.sleep(5) # 停留5秒是為了避免消費者的第一個頁面都沒請求下來的時候,生產(chǎn)者就直接判斷無數(shù)據(jù),從而自行終止程序。for i in range(4): # 啟動5個生產(chǎn)者t2 = Consumer(Page_queue, Photo_queue)t2.start()if __name__ == '__main__':main()經(jīng)過實驗之后,下載速度快多了,結(jié)果如下:
這樣子我們就可以實現(xiàn)多線程下載斗圖表情包,下一次和朋友斗圖,再也不怕沒有表情包了。
總結(jié)
以上是生活随笔為你收集整理的斗图高手教你用Python批量爬取表情包的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: p2p终结者在交换机上的机器用P2P终结
- 下一篇: 解决Steam下载不了(缺失文件权限)的