Python爬蟲實戰之(三)| 一個海賊迷的吶喊

做者:xiaoyu
微信公衆號:Python數據科學
知乎:Python數據分析師html


<10>

海賊王已經10年了,一路陪伴了咱們的點點滴滴。它熱血,激情,感人,歡樂,吸引了無數男女老幼的牢牢跟隨。
提及來還真有點當心酸,原諒博主也是個海賊迷,心中懷揣着很大的夢想,誓死也要成爲海賊王的男人。
但現在夢想已經破滅了,由於博主有了女友...git

clipboard.png

什麼?說我是假粉絲,我上去就給你一巴掌!看到最後你就知道什麼叫真粉兒!!github

clipboard.png

好了,收!

爬取目標

說說咱們的正題,前面兩篇爬蟲學習介紹了正則BeautifulSoup的內容,這裏實際上是想借着這個機會給你們分享一下正則BeautifulSoup解析的實戰例子。服務器

目標實現比較簡單,就是下載xxx網站上海賊王動漫的套圖。爬取效果以下:微信

clipboard.png
(截取了部分下載過程)多線程

clipboard.png
(部分下載圖片)app

採起了多線程爬取,總共1000多張,都存在本地了。運維

功能分析

本篇目的是使用正則+BeautifulSoup,所以後面不更多贅述了。dom

提取系列連接

clipboard.png

經過開發者工具看到,全部的系列都是同一級別的節點,那麼咱們首先應該作的是遍歷全部頁碼,而後提取每頁各個系列的連接。工具

接下來看看連接在哪。

clipboard.png
小提示:紅框內第一個是鼠標自動跟隨,第二個是手機/PC切換,使用起來很是方便。

具體點開其中一個系列標籤一看,咱們要的連接正是<a>標籤下的href屬性,可是你會發現有兩個如出一轍的href屬性,連接也同樣,而咱們只須要一個,這就須要小處理一下了,提供兩個思路:

  • 使用BeautifulSoup方法單獨提煉出一個連接
  • 兩個連接都提煉出來,放進set集合中去重

這裏博主用的第一種方法。

提取系圖片連接

clipboard.png

一樣的過程,圖片的連接在<p>標籤下的子節點<img>的src屬性裏,依然使用BeautifulSoup就可輕鬆解決。

可是這裏的網頁排版有個問題,就是有的系列中多組圖在一頁中,而有的系列每頁只有一張圖,須要翻頁查看。

解決方法是無論有沒有翻頁,都直接遍歷該系列下的全部頁,經過返回的狀態碼來判斷下一步動做。

好了,解析的任務的分析差很少完成了,下面看看具體代碼如何實現的。

代碼實現

下載系列連接:

def html_parse(self, num):
    try:
        url_make = self.url.format(num)
        html = requests.get(url_make, timeout=10)
        soup = BeautifulSoup(html.content, 'lxml')
        ul_tag = soup.find_all('ul', class_='spic pic1')
        soup1 = BeautifulSoup(str(ul_tag[0]), 'lxml')

        for counter, li_tag in enumerate(soup1.find_all('li')):
            soup2 = BeautifulSoup(str(li_tag), 'lxml')
            a_tag = soup2.find_all('a')
            href_list = re.findall(re.compile('href="(.+?)"'), str(a_tag))
            if len(href_list) != 0:
                print('第 ' + str(num) + ' 頁: ----第 ' + str(counter + 1)
                      + '個連接:' + href_list[0] + ' ----')
                self.q.put(href_list[0])
        sleep(random.randint(2, 3))
    except requests.ConnectionError:
        pass

下載圖片連接:

def picture_parse(self):
        try:
            sub_url = self.q.get()
            sub_url_base = sub_url[:-6]
            for page in range(1, 10):
                sub_url_new = sub_url_base + '_' + str(page) + '.shtml'

                html2 = requests.get(sub_url_new)
                if html2.status_code == 200:
                    soup = BeautifulSoup(html2.content, 'lxml')
                    div_tag = soup.find_all('div', id='pictureContent')
                    soup1 = BeautifulSoup(str(div_tag[0]), 'lxml')

                    for img_tag in soup1.find_all('img', src=re.compile('.+?')):
                        soup3 = BeautifulSoup(str(img_tag), 'lxml')
                        if soup3.img['src'] is not None:
                            self.picture_link.append(soup3.img['src'])
                            print(str('----' + soup3.img['alt']) + '連接 : '
                                  + str(soup3.img['src']) + ' ----')
                    sleep(random.randint(2, 3))
                else:
                    pass
        except requests.ConnectionError:
            pass

下載並儲存圖片到本地:

def picture_store(self):
    try:
        for num, link in enumerate(set(self.picture_link)):
            html3 = requests.get(link)
            picture_path = 'D:\Pictures_Downloaded\\' + 'pic' + str(num+1) + '.jpg'
            with open(picture_path, 'wb') as f:
                f.write(html3.content)
    except requests.ConnectionError:
        pass

多線程隊列任務:

def main(self):
    page_num = 2
    threads_0 = []
    for i in range(1, page_num):
        t = Thread(target=self.html_parse, args=(i,), name='Thread-0')
        threads_0.append(t)
    for i in range(len(threads_0)):
        threads_0[i].start()
    for i in range(len(threads_0)):
        threads_0[i].join()

    threads_1 = []
    for i in range(self.q.qsize()):
        t1 = Thread(target=self.picture_parse, args=(), name='Thread-1')
        threads_1.append(t1)
    for i in range(len(threads_1)):
        threads_1[i].start()
    for i in range(len(threads_1)):
        threads_1[i].join()

    self.picture_store()

注:爬取間隔能夠適當再長點,減輕目標服務器的負擔,也理解一下辛苦的運維工做人員。

代碼比較簡單,目的是在實戰中掌握正則和BeautifulSoup解析方法,歡迎你們指點和討論。

完整代碼已上傳到Github,請參考:https://github.com/xiaoyusmd/...

做品展現

這部分是爲了兌現鐵粉兒的承諾,不感興趣可忽略。

博主庫愛畫畫,素描,水彩,國畫都學過點,固然這個是在wacom繪畫板上,利用corel painter + photoshop完成的。因爲熱愛海賊王動漫,閒暇時間畫了個各類海賊繪畫。

如下是幾張索隆桑的繪圖(無水印),感興趣的朋友能夠收藏:)
圖片描述
圖片描述
圖片描述


關注微信公衆號Python數據科學,獲取 120G 人工智能 學習資料。

圖片描述

圖片描述

相關文章
相關標籤/搜索