爬蟲實戰——爬取mzitu.com(慘遭反扒案例失敗)

来源:https://www.cnblogs.com/mrkr/archive/2020/03/19/12521641.html
-Advertisement-
Play Games

本次過程僅供學習參考,請遵守相關法律法規。 首先我們分析網站:https://www.mzitu.com/all/ 不難發現,這個頁面上包含了大量的圖片鏈接,可以說是特別方便我們爬取圖片的,這是件好事。那麼我們繼續分析 這是第一頁的地址 這是第二頁的,所以我們爬取的時候只需要在鏈接後面增加“/num ...


本次過程僅供學習參考,請遵守相關法律法規。

 

首先我們分析網站:https://www.mzitu.com/all/

 

 

 不難發現,這個頁面上包含了大量的圖片鏈接,可以說是特別方便我們爬取圖片的,這是件好事。那麼我們繼續分析

 

 

 

 這是第一頁的地址

 

 

 這是第二頁的,所以我們爬取的時候只需要在鏈接後面增加“/num”即可

那麼我們先來爬取首頁的內容

import  requests
import re
#爬取首頁
url = 'https://www.mzitu.com/all/'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
}
response = requests.get(url, headers = header).text
print(response)

我們可以得到以下

 

 

 

 ok 接下來我們需要從中提取我們想要的鏈接

 

#使用正則表達式提取需要的鏈接
req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:
print(url,pic_name)

這樣我們就獲得了我們需要的鏈接了

 

 

 

 

那麼接來下我們需要知道的是每個鏈接裡面到底有多少頁呢

我們進一步分析網頁觀察頁面源碼我們可以發現

 

 

 

我們可以從頁面中提取到最後一頁的內容

req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:
    print(url,pic_name)
    #獲取每個url內的總頁面數目
    html = requests.get(url, headers=header).text
    req_last = "<a href='.*?'><span>&laquo;上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁&raquo;</span></a>      </div>"
    last_num = re.findall(req_last,html)
    print(last_num)
    exit()

 

我們使用正則將所需要的最後一頁的頁碼提取出來即可獲得結果

 

 

 那麼接下來就是拼接url了

 我們嘗試在原本的第一頁的url後添加“/1”發現也可以進入我們需要的頁面這大大降低了代碼量

#將列表轉化為int
    for k in last_num:
        k=k
    k = int(k)
    #拼接url
    for i in range(1,k):
        url_pic = url + '/' + str(i)
        print(url_pic)
    exit()

ps:這裡的“exit()”是為了方便測試程式只要獲得一個主url下的地址即可 後面將會刪去

我們可以得到下麵的鏈接

 

 這些鏈接打開都是有效的但是我們打開的並不直接是圖片的url

所以我們還要進一步對信息進行篩選,再優化一下代碼

#將列表轉化為int
    for k in last_num:
        k=k
    k = int(k)
    #拼接url
    for i in range(1,k):
        url_pic = url + '/' + str(i)

        headerss = {
            'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"',

            'Referer': url_pic,
            'Host': 'www.mzitu.com'
        }

        html_pic_last = requests.get(url_pic, headers=headerss).text
        req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>'
        req_pic_url =  re.findall(req_last_pic,html_pic_last)
        for link in req_pic_url:
            link = link
        links = str(link)
        print(links)
        image_content = requests.get(links, headerss).content
        print(image_content)
        # with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f:

            # f.write(image_content)
        exit()

 

可是經過測試,發現保存下來的圖片無法打開,檢查發現再最後一步下載圖片的時候發生了403錯誤:伺服器拒絕訪問

 

 我試著換了herder可是還是不行,所以GG了!

 

附上目前為止全部源碼

import  requests
import re
#爬取首頁
url_head = 'https://www.mzitu.com/all/'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
    'Referer' :'https://www.mzitu.com'
}
response = requests.get(url_head, headers = header).text
#使用正則表達式提取需要的鏈接
req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:
    #獲取每個url內的總頁面數目
    html = requests.get(url, headers=header).text
    req_last = "<a href='.*?'><span>&laquo;上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁&raquo;</span></a>      </div>"
    last_num = re.findall(req_last,html)
    #將列表轉化為int
    for k in last_num:
        k=k
    k = int(k)
    #拼接url
    for i in range(1,k):
        url_pic = url + '/' + str(i)

        headerss = {
            'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"',
            'Referer': url_pic,        
        }
        html_pic_last = requests.get(url_pic, headers=headerss).text
        req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>'
        req_pic_url =  re.findall(req_last_pic,html_pic_last)
        for link in req_pic_url:
            link = link
        links = str(link)
        print(links)
        image_content = requests.get(links, headerss).content
        print(image_content)
        # with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f:

            # f.write(image_content)
        exit()
    exit()

 分析了一下我的代碼 發現

 

 這裡的headers沒有給出定義,可能因為這個出現了bug 我修改了一下

image_content = requests.get(links, headers = headerss).content

這樣測試一下

 

 我們成功了!

完善代碼

import  requests
import re
#爬取首頁
url_head = 'https://www.mzitu.com/all/'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
    'Referer' :'https://www.mzitu.com'
}


response = requests.get(url_head, headers = header).text


#使用正則表達式提取需要的鏈接

req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:

    #獲取每個url內的總頁面數目
    html = requests.get(url, headers=header).text
    req_last = "<a href='.*?'><span>&laquo;上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁&raquo;</span></a>      </div>"
    last_num = re.findall(req_last,html)
    #將列表轉化為int
    for k in last_num:
        k=k
    k = int(k)
    #拼接url
    for i in range(1,k):
        url_pic = url + '/' + str(i)

        headerss = {
            'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"',

            'Referer': url_pic

        }

        html_pic_last = requests.get(url_pic, headers=headerss).text
        req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>'
        req_pic_url =  re.findall(req_last_pic,html_pic_last)
        for link in req_pic_url:
            link = link
        links = str(link)
        print(links)
        image_content = requests.get(links, headers = headerss).content
        #保存圖片
        with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f:
            f.write(image_content)

 增加一點用戶體驗後的代碼

import  requests
import re
#爬取首頁
sum = 0
url_head = 'https://www.mzitu.com/all/'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
    'Referer' :'https://www.mzitu.com'
}


response = requests.get(url_head, headers = header).text


#使用正則表達式提取需要的鏈接

req = '<br>.*?日: <a href="(.*?)" target="_blank">(.*?)</a>'
urls = re.findall(req,response)
for url,pic_name in urls:

    #獲取每個url內的總頁面數目
    html = requests.get(url, headers=header).text
    req_last = "<a href='.*?'><span>&laquo;上一組</span></a><span>1</span><a href='.*?'><span>2</span></a><a href='.*?'><span>3</span></a><a href='.*?'><span>4</span></a><span class='dots'>…</span><a href='.*?'><span>(.*?)</span></a><a href='.*?'><span>下一頁&raquo;</span></a>      </div>"
    last_num = re.findall(req_last,html)
    #將列表轉化為int
    for k in last_num:
        k=k
    k = int(k)
    #拼接url
    for i in range(1,k):
        url_pic = url + '/' + str(i)

        headerss = {
            'User-Agent': '"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"',

            'Referer': url_pic

        }

        html_pic_last = requests.get(url_pic, headers=headerss).text
        req_last_pic = '<div class=.*?><p><a href=.*? ><img src="(.*?)" alt=.*? width=.*? height=.*? /></a></p>'
        req_pic_url =  re.findall(req_last_pic,html_pic_last)
        for link in req_pic_url:
            link = link
        links = str(link)
        print('成功下載地址'+links+"的圖片")
        sum = sum +1
        image_content = requests.get(links, headers = headerss).content
        #保存圖片
        with open("image/" + pic_name+ str(i) + ".jpg", "wb") as f:
            f.write(image_content)
        print("一共下載了"+str(sum)+"張圖片")

 

讓我們來看看最後的成果吧

 

 

 

 

 

 

本文由作者親自撰寫,如有不足各位大佬提出來,如需轉載請標明出處,謝謝


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • css3相較於css2.1增加了許多新的特性功能,目前主流瀏覽器chrome、safari、firefox、opera、甚至360都已經支持了CSS3大部分功能了,IE10以後也開始全面支持CSS3了,需要註意的是css3樣式在不同的瀏覽器可能需要不同的首碼(是瀏覽器的私有屬性,相容性),此外在代碼... ...
  • 'use strict' //引入node.js路勁模塊 const path = require('path') //引入utils工具模塊,utils主要用來處理css-loader和vue-style-loader的 const utils = require('./utils') //引入c ...
  • zepto中的DOM操作 插入操作 append appendTo 插在最後一個子元素後面 prepend prependTo 插在第一個子元素前面 after insertAfter 插在該元素後面,作為兄弟元素 before insertbefore 插在該元素後面,作為兄弟元素 <!DOCTY ...
  • vue前端項目中開發基於甘特圖的項目計劃模塊 參考鏈接 相比以前jquery的資料,vue的甘特圖插件少很多,中文資料更是少的可憐,以下兩個鏈接是在網上搜到相對還不錯的甘特圖插件 "https://www.cnblogs.com/liang715200/p/12029640.html" "https ...
  • [toc] 運用領域模型 交流與語言的使用 非原創,感謝《領域驅動設計》這本書 領域模型可成為軟體項目通用語言的核心。該模型是一組得自於項目人員頭腦中的概念,以及反映了領域深層含義的術語和關係。這些術語和相互關係提供了模型語言的語義,雖然語言是為領域量身定製的,但就技術開發而言,其依然足夠精確。正是 ...
  • [toc] 運用領域模型 消化知識 非原創,感謝《領域驅動設計》這本書 有效建模的要素 (1) 模型和實現的綁定。最初的原型雖然簡陋,但它在模型與實現之間建立了早期鏈接,而且在所有後續的迭代中我們一直在維護該鏈接。 (2) 建立了一種基於模型的語言。隨著項目的進展,雙方都能夠直接使用模型中的術語,並 ...
  • 設計模式中的原則和法則: 1、開閉原則: 開閉原則(Open Closed Principle,OCP)由勃蘭特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向對象軟體構造》(Object Oriented Software Construction)中提出:軟體實體應當對 ...
  • 1、最簡單的用戶系統 一個最簡單的用戶系統,只需要有用戶和身份驗證兩個模塊就夠了。如圖: 這裡提示一下:上層數據依賴下層數據。舉個慄子,就是身份驗證需要依賴用戶數據。 2、具有許可權管理的用戶系統 如果需要進行許可權管理的話,那麼就加上資源和角色模塊。同時,在身份認證之後需要按需進行鑒權。 資源和用戶都 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...