天天看點

Python3 學習劄記(三)

參考‘逆風的薔薇’的教程,《Python3爬蟲》-爬取豆瓣首頁圖檔

代碼

采用僞裝浏覽器形式,增加圖像處理和存儲子產品。

'''
re子產品提供對正規表達式的支援
os子產品提供對系統接口層面的支援
'''

import urllib.request, re, os

targetPath = r'E:\Python\VSCode_Python\CSDN\project\03_dbImages'

def saveFile(path):
    # 路徑有效性檢測
    if not os.path.isdir(targetPath):
        os.mkdir(targetPath)    # 如果沒有該路徑就生成該路徑

    # 設定圖檔路徑
    pos = path.rindex('/')  # 傳回/在字元串中最後出現的位置,以擷取圖檔名稱
    t = os.path.join(targetPath, path[pos+:])
    return t    # saveFile用于生成一個路徑,配合urlretrieve使用

url = 'https://www.douban.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36'}
req = urllib.request.Request(url=url, headers=headers)

res = urllib.request.urlopen(req)

data = res.read()

# re.findall(pattern, string, flags=0) 搜尋string,以清單形式傳回全部能比對的字元串
# 正規表達式,https:[^s]*?(jpg|png|gif),[^\s]表示比對非空格,*表示比對前面的表達式任意次,?表示非貪婪比對,(jpg|png|gif)表示比對jpg或png或gif
# * +等都是貪婪比對,後面再加?則變成非貪婪比對
# re.match,隻比對字元串的開始,如果開始不比對則比對失效傳回None
# re.search,比對整個字元串,直到找到一個比對
# re.findall,周遊整個字元串
for link, t in re.findall(r'(https:[^\s]*?(jpg|png|gif))', str(data)):

    print(link)
    try:
        urllib.request.urlretrieve(link, saveFile(link))
        # urlretrieve(url, filename=None, reporthook=None, data=None) 将link連結上的這張圖檔拷貝至本地filename路徑
        print('儲存成功')
    except:
        print('儲存失敗')

print('Done!')
           

運作結果

控制台輸入如下:

Python3 學習劄記(三)

抓取的圖檔如下:

Python3 學習劄記(三)

筆記

  • os子產品,提供系統接口層面的支援,掌握isdir、mkdir、path.rindex和join等的使用,相關說明OS子產品
  • re子產品,提供對于正規表達式的支援,掌握match、search、findall等的使用以及基本的正規表達式規則,相關說明re子產品
  • urlretrieve的使用
  • 原教程中正規表達式為

抓取的圖檔要少一些,而更正為

抓取的圖檔更為全面。[^\s]表示比對非空格字元,而如果說[^s]表示比對非s又說不通,因為根據原表達式沒有s但是有空格的也沒有比對成功,這裡暫時不太明白。

  • 有朋友對循環的表示有疑問,為什麼要用link,t兩個變量,一個不可以嗎?
for link, t in re.findall(r'(https:[^\s]*?(jpg|png|gif))', str(data)):
           

可以看一下經過re.findall處理之後的結果,是一組清單,清單中每個元素包含兩個字元串,圖檔的網址以及圖檔的格式,而我們在進行urlretrieve處理時隻需要圖檔的網址,是以用了link和t兩個變量,如果隻用link,隻需将後面的link改為link[0]也沒有問題。

Python3 學習劄記(三)