1. 程式人生 > >Python爬蟲實戰 requests+beautifulsoup+ajax 爬取半次元Top100的cos美圖

Python爬蟲實戰 requests+beautifulsoup+ajax 爬取半次元Top100的cos美圖

1.Python版本以及庫說明

Python3.7.1 Python版本
urlencode 可將字串以URL編碼,用於編碼處理
bs4 解析html的利器
re 正則表示式,用於查詢頁面的一些特定內容
requests 得到網頁html、jpg等資源的lib
os 建立資料夾需要用到系統操作lib
time 時間模組,獲取日期建立資料夾
html5lib 解析模組
lxml 解析模組
multiprocessing 多執行緒模組

2.IDE

Pycharm

3.瀏覽器頁面檢查工具

QQ瀏覽器

4.爬蟲抓取過程分析

4.1https請求的uesr_head引數設定

agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' \
        '(KHTML, like Gecko) Chrome/63.0.3239.26 ' \
        'Safari/537.36 Core/1.63.6721.400 QQBrowser/10.2.2243.400'
headers = {
    'user-agent': agent

4.2分析top100列表頁面(利用ajax獲得全部資料)

頁面地址是https://bcy.net/coser/toppost100

進入頁面發現只有前30名的圖片,但當我們下拉可以發現,頁面動態載入了全部的COS圖,利用頁面檢查功能 我們分析這是一個ajax請求,我們可以通過構造ajax請求來獲得全部圖片

我們開啟頁面檢查工具,選擇Network,然後在選擇XHR,也就是ajax的核心——XMLHttpRequest物件,我們看到初始頁面僅有兩個檔案,下拉使會產生新的檔案,我們檢視新檔案的Query String Parameters可以發現其傳送了一組json資料

        'p': 2,   
        'type': 'week',
        'data': ''

我們可以推斷p應該代表頁碼,type應該代表這是本週熱門的資料

我打算通過構造url直接獲取資料時發現頁面404,這也是我對與前端以及ajax不熟悉的原因吧

    params = {
        'p': page,
        'type': 'week',
        'data': ''
    }
    base_url = 'https://bcy.net/coser/toppost100'
    url = base_url + urlencode(params)

查了查資料,也不是很懂,最後我直接XHR產生的新檔案,頓時醒悟,我來到了這樣的頁面

我們看到頁面的url是https://bcy.net/coser/index/ajaxloadtoppost?p=2&type=week&date=
自己手動修改p=2中的值就可以獲得圖片的頁面了

4.3soup物件查詢原始碼中的連結

首先查詢li標籤

all_li = soup.find_all('li', class_=re.compile('js-smallCards _box'))

然後查詢li的標籤中的a標籤 提取href

    urls = []
    for li in all_li:
        a = li.find('a')
        urls.append(a['href'])
    return urls

4.4進入頁面連結,遍歷讀取所有圖片

一開始還想繼續利用soup進行解析,發現python讀取頁面後並沒有找到那些標籤,一度再次陷入困境,最後在js檔案中發現了想要的資料

我們發現圖片路徑都是類似的

\"path\":\"https:\\u002F\\u002Fimg-bcy-qn.pstatp.com\\u002Fuser\\u002F2511464\\u002Fitem\\u002Fc0juk\\u002F0ed91266f72b4f73b5f4bfec1c0ebac0.jpg\\u002Fw650\"

(這部分中應該有關於編碼解碼還有路徑名的一些東西,但我還不是很熟悉)
我們可以利用re正則表示式模組提取path
設定頭部path尾部w650

    pattern = re.compile('"path(.*?)w650', re.S)
    items = re.findall(pattern, content)

對其中的\u002F進行替換,去掉尾部的\w650,得到正確的url

for i in range(len(items)):
    items[i] = items[i].replace(r'\\u002F', '/')
    items[i] = items[i][5:-1]

其他步驟應該就沒有什麼問題了

4.5建立資料夾分類下載儲存圖片

獲取標題,以標題為名建立資料夾,需要去掉非法的一些符號

soup = BeautifulSoup(content, 'html5lib')
title = soup.title.string
unvalid_str = '<>,\/|,:,"",*,?'
for ch in unvalid_str:
    title = title.replace(ch, '')

4.6嘗試多執行緒進行爬取提高速度

    pool = Pool()
    # 一共6組ajax請求
    groups = ([x+1 for x in range(6)])
    # map()實現多執行緒下載
    pool.map(main, groups)
    # 關閉
    pool.close()
    # 如果主執行緒阻塞後,讓子程序繼續執行完成之後,在關閉所有的主程序
    pool.join()

4.7最終結果展示




5.Github專案地址

https://github.com/hlcoxndgw/BanciyuanBcyTopCosplaySpider

歡迎大家star

6.總結

  • 半次元網站應該沒有什麼反爬蟲的措施,所有在程式碼也沒有進行IP代理或者抓取等待的設定
  • COS原圖檔案還是很大的,爬取TOP100的所有圖片應該需要很多的流量(我爬取完成發現資料夾大小是6GB。。。)
  • 一些COSer設定了僅對粉絲可見,沒有對這種情況進行處理,所有這種情況會得到一個空資料夾
  • 網站頁面內容隨時可能變化,導致程式碼無法執行,但爬取的原理基本不會變化
  • 第一次寫部落格,可能存在許多問題,有什麼不足的地方或者有什麼疑問都可以在評論區指出,謝謝大家