零基礎爬取堆糖網圖片(二)---多線程版

零基礎爬取堆糖網圖片(二)---多線程版

全文介紹:

接着上篇文章,咱們已經實現圖片的下載,可是咱們發現整個爬取過程當中,由於使用了for循環嵌套,致使每次遍歷,都會打開文件在關閉,打開文件在關閉(套娃)。因此須要注意for循環的使用,其次下載圖片是整個程序中最耗時的,若是須要提高爬取速度,那麼咱們能夠從這個方向入手,實現多線程爬取python

涉及內容:

  1. 爬蟲基本流程
  2. requests庫基本使用
  3. urllib.parse模塊
  4. threading模塊

圖例說明:

  1. 請求與響應
sequenceDiagram 瀏覽器->>服務器: 請求 服務器-->>瀏覽器: 響應
  1. 爬蟲基本流程
graph TD A[目標網站] -->|分析網站| B(url) B --> C[模擬瀏覽器請求資源] C -->D[解析網頁] D-->E[保存數據]

正文:

1.導入

import urllib.parse
import threading
import requests

2.發送請求,獲取響應

def get_page(url):
    page = requests.get(url)
    page = page.content
    # 將 bytes 轉化爲 字符串
    page = page.decode('utf-8')

    return page

3.關鍵字以及翻頁

def pages_from_duitang(label):
    url = 'https://www.duitang.com/napi/blog/list/by_search/?kw={}&start={}'
    pages = []
    # 將中文轉化成url編碼
    label = urllib.parse.quote(label)
    # 0-3600 步長100
    for index in range(0, 3600, 100):
        # 將這兩個變量替換佔位符{}
        u = url.format(label, index)
        print(u)
        page = get_page(u)
        pages.append(page)
    return pages

4.獲取一個頁面上的全部圖片子連接

def findall_pages(page, startpart, endpart):
    all_string = []
    end = 0
    # -1表明找不到 意思就是匹配到就執行循環
    while page.find(startpart, end) != -1:
        # 匹配第一個字符,從下標0開始匹配到的位置下標,並將字符長短傳給start變量
        start = page.find(startpart, end) + len(startpart)
        # 將從第一個須要匹配的字符串後面的字符開始,匹配第二個須要匹配的字符出現的位置,並將這個下標值賦給end變量
        end = page.find(endpart, start)
        # 切片 取兩個所要匹配字符 之間的部分也就是圖片url
        string = page[start:end]
        # 存入列表
        all_string.append(string)
    return all_string

5.爬取所有頁面

def pic_url_from_pages(pages):
    pic_url = []
    for page in pages:
        url = findall_pages(page, 'path":"', '"')
        pic_url.extend(url)     # 合併列表
    return pic_url

6.下載圖片

def pic_download(url, n):
    r = requests.get(url)
    path = r"C:\Users\Mark\Desktop\新建文件夾 (2)\%s.jpg" %n
    with open(path, 'wb')as d:
        d.write(r.content)

7.調用函數

以前的函數就像是一個一個的零件,如今咱們要拼裝這些零件,這個車纔開的起來!😏api

def main(label):
    pages = pages_from_duitang(label)
    pic_url = pic_url_from_pages(pages)
    n = 0
    for url in pic_url:
        n += 1
        print('正在下載第 {} 張圖片'.format(n))
        pic_download(url,n)
        
main('校花')

已完成瀏覽器

  • [x] 函數封裝
  • [ ] 多線程

8.多線程的實現

栗子來了服務器

排隊上廁所:商城常常會有人排隊上廁所,而一個廁所(進程)是能夠有多個坑位(線程),每當有位置空着時就會有下一我的進來,進來後爲了讓別人知道這個位置有人了(避免爭奪),避免尷尬,須要上鎖,完事兒,出來時解鎖就行,而後再有一我的進來......多線程

  1. 首先設置信號量
thread_lock = threading.BoundedSemaphore(value=5)   # value 能夠改,但不可過大
  1. 而後就是主函數中對於下載圖片這個函數使用多線程
def main(label):
    pages = pages_from_duitang(label)
    pic_url = pic_url_from_pages(pages)
    n = 0
    for url in pic_url:
        n += 1
        print('正在下載第 {} 張圖片'.format(n))
        # 上鎖
        thread_lock.acquire()
        ## 下載 這個方法丟進線程池
        t = threading.Thread(target=pic_download, args=(url, n))
        t.start()
        pic_download(url,n)

        
main('英雄聯盟')
  1. 圖片下載完畢,須要解鎖
thread_lock.release()

效果:

注意身體,就不放過多的正能量圖片了app

相關文章
相關標籤/搜索