[記錄][python]python爬蟲,下載某圖片網站的所有圖集

来源:http://www.cnblogs.com/CaDevil/archive/2016/10/14/5958770.html
-Advertisement-
Play Games

該隨筆是記錄我的第一個python程式,一個爬去指定圖片站點的所有圖集,現在還是一個非常簡陋的單線程程式。下一步是改寫成多線程,雖然python多線程被詆毀得一塌糊塗。同時加上異常處理。 近來練習python程式,仿照別人的爬蟲寫一個自己的爬蟲來練練手。在編寫的過程中遇到各種問題,中文編碼、請求不到 ...


  

隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

 

  該隨筆是記錄我的第一個python程式,一個爬去指定圖片站點的所有圖集,現在還是一個非常簡陋的單線程程式。下一步是改寫成多線程,雖然python多線程被詆毀得一塌糊塗。同時加上異常處理。

  近來練習python程式,仿照別人的爬蟲寫一個自己的爬蟲來練練手。在編寫的過程中遇到各種問題,中文編碼、請求不到html等問題。撰寫該隨筆的目的是將所遇到的問題記錄下來,並提供相應的解決方法。當然這些解決方法是參照其他人提供的,東抄抄西抄抄,^_^。

   先大致描述下代碼過程中遇到的問題: 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

  •  html中文解碼

  雖然beautifulsoup預設的編碼方式是utf-8,而且國內部分站點的編碼方式是utf-8。還是需要手工設置一下中文的編碼方式。

  在BeautifulSoup中手工設置編碼方式如下所示

encoding = "gb18030"
soup = BeautifulSoup(html,from_encoding=encoding)  

  

  •  list的append和extend使用 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

  查詢相關資料,list中的append是向list插入一個值,extend則是將一個list插入另一個list中;

  若要將list1併入list2中,則使用list2.extend(list1);

  若向list中插入值的話,使用list.append(vale)

 

  •  beautifulsoup返回的值,可以直接查找符合條件的節點

   beautifulsoup返回的值是一顆語法樹,結果與html dom結構差不多[這個地方有些保留,我目前不是太瞭解dom結構],通過find和find_all去查找相應的標簽。前者返回一個標簽的對象,後者返回list,該list的值是多個對象。

 

  •  將urllib.urlretrieve()儘量偽裝成一個用戶。

  使用 urlretrieve之前,將發送的http請求做些簡單的偽裝,儘量偽裝成為一個用戶,避免站點不響應下載請求。若不設置的話,通過wireshark,可以查看到下載請求的user-agent的值與python有關,伺服器可能會將下載請求給忽略掉。同時還可以添加上referer,有些站點通過referer來判斷盜鏈。若不設置的話,下載的圖片全是防盜鏈提示圖片。 隨筆僅用於學習交流,轉載時請註明出處,http://www.cnblogs.com/CaDevil/p/5958770.html

        #偽裝一下下載的http請求,否則有些站點不響應下載請求。
        #不設置的話,下載請求中的user-agent為python+版本號
        urllib.URLopener.version = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0'
        #下載圖片到指定目錄中,保留圖片在伺服器上的文件名
        urllib.urlretrieve(imgurl,downloadpath)

  

  廢話有些多,上代碼。為了避免宣傳圖片站點的嫌疑,不放該站點的鏈接。 代碼僅用於學習交流。

import urllib2
import io
import random
import urllib
from bs4 import BeautifulSoup
import re
import os

import sys
reload(sys)
sys.setdefaultencoding('utf8')

def getHtml(url):
    #儘可能讓爬蟲顯示為一個正常用戶。若不設置,則發送的請求中,user-agent顯示為Python+版本
    user_agent = [
        'Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30',
        'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)',
        'Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.9.168 Version/11.50',
        'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C)'        
    ]
    #設置網頁編碼格式,解碼獲取到的中文字元
    encoding = "gb18030"
    #構造http請求頭,設置user-agent
    header = {"User-Agent":random.choice(user_agent)}
    #構造發送請求
    request = urllib2.Request(url,headers=header)
    #發送請求,獲取伺服器響應回來的html頁面
    html = urllib2.urlopen(request).read()
    #使用beautifulSoup處理的html頁面,類似dom
    soup = BeautifulSoup(html,from_encoding=encoding)
    return soup

# 獲取整個站點所有圖集的頁碼
def getPageNum(url):
    soup = getHtml(url)
    # 直接在站點首頁獲取所有圖集的總頁碼
    nums=soup.find_all('a',class_='page-numbers')
    # 除掉“下一頁”的鏈接,並獲取到最後一頁
    totlePage = int(nums[-2].text)
    return totlePage

#獲取指定頁面下圖集名稱和鏈接
def getPicNameandLink(url):
    
    soup = getHtml(url)
    meun = []
    #類似html dom對象,直接查找id為“pins”的ul標簽,返回的結果是一個dom對象
    targetul = soup.find("ul",id="pins")
    if targetul:    
        #獲取該ul下所有的超鏈接,返回值的類型是list,find_all中第二個參數表示某個指定標簽的屬性
        pic_list = targetul.find_all("a",target="_blank")
        if pic_list:
           # 遍歷所有指定的標簽a
            for pic in pic_list:
                #獲取圖集的鏈接
                link = pic["href"]
                picturename = ""
                #找到標簽a中,“class”為“lazy”的img標簽。
                #find中,第二個參數表示某個指定標簽的屬性。
                #在python中class是保留字,所有標簽的class屬性的名稱為“class_”
                img = pic.find("img",class_='lazy')
                if img:
                    # 保證中文字元能夠正常轉碼。
                    picturename = unicode(str(img["alt"]))
                else:
                    continue
                #插入圖集名稱和對應的url
                meun.append([picturename,link])    
        
        return meun
    return None

#function獲取所有的圖集名稱
def getallAltls(url):
    totalpage = getPageNum(url)
    #獲取首頁中所有的圖集名稱。首頁的url和其他頁面不同,沒有page
    meun = getPicNameandLink(url)
    #迴圈遍歷所有的圖集頁面,獲取圖集名稱和鏈接
    for pos in range(2,totalpage):
        currenturl = url + "/page/" + str(pos)
        #getPicNameandLink()返回的值是一個list。
        #當一個list插入到另一個list中時,使用extend。
        #若是插入一個值時,可以用append
        meun.extend(getPicNameandLink(currenturl))
    
    return meun
    
# 獲取從首頁到指定頁面所有的圖集名稱和鏈接
def getparAltls(url,page):
    meun = getPicNameandLink(url)
        
    for pos in range(2,page):
        currenturl = url + "/page/" + str(pos)
        meun.extend(getPicNameandLink(currenturl))
        
    return meun

#獲取單個相冊內圖片頁碼
def getSinglePicNum(url):
    soup = getHtml(url)
    #pagenavi還是一個對象(Tag),可以通過find_all找出指定標簽出來
    pagenavi = soup.find("div",class_="pagenavi")
    pagelink = pagenavi.find_all("a")
    
    num = int(pagelink[-2].text)
    return num


#下載單個相冊中的所有圖片
def getSinglePic(url,path):
    totalPageNum = getSinglePicNum(url)
    #從第一頁開始,下載單個圖集中所有的圖片
    #range()第二個參數是範圍值的上限,迴圈時不包括該值
    #需要加1以保證讀取到所有頁面。
    for i in range(1,totalPageNum + 1):
        currenturl = url + "/" + str(i)
        downloadpic(currenturl,path)
       
#下載單個頁面中的圖片 
def downloadpic(url,path):
    soup = getHtml(url)
    #找出指定圖片所在父容器div
    pageimg = soup.find("div",class_="main-image")
    
    if pageimg:
        #找出該div容器中的img,該容器中只有一個img
        img = pageimg.find("img")
        #獲取圖片的url
        imgurl = img["src"]
        #獲取圖片的文件名
        restring = r'[A-Za-z0-9]+\.jpg'
        reimgname = re.findall(restring,imgurl)
        
        #將圖片保存在指定目錄下
        path = str(path)
        if path.strip() == "":
            downloadpath = reimgname[0]
        else:
            downloadpath = path + "/" + reimgname[0]
        #偽裝一下下載的http請求,否則有些站點不響應下載請求。
        #不設置的話,下載請求中的user-agent為python+版本號
        urllib.URLopener.version = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0'
        #下載圖片到指定目錄中,保留圖片在伺服器上的文件名
        urllib.urlretrieve(imgurl,downloadpath)
    
def downimgofsite(url,path = ""):
    
    path = str(path)
    #獲取所有圖集的名稱和鏈接
    meun_list = getallAltls(url)
    directorypath = ""
    
    for meun in meun_list:
        directoryname = meun[0]
        if path.strip() != "":
            directorypath = path + "/" + directoryname
        else:
            directorypath = os.getcwd + "/" + directoryname
        
        if not os.path.exists(directorypath):
            os.makedirs(directorypath)
        
        getSinglePic(meun[1], directorypath)
        

if __name__ == "__main__":
   
    
   # page = 8
    url = "XXXXX"
    menu = getallAltls(url)
    #menu = getparAltls(url, page)  
    
    f = open("tsts.txt","a")
    for i in menu:
        f.write(str(unicode(i[0]))+"\t"+str(i[1])+"\n")
    f.close()
       
    
View Code

 


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

-Advertisement-
Play Games
更多相關文章
  • ASP.NET Core請求處理管道由一個伺服器和一組中間件構成。如果想非常深刻地認識ASP.NET Core的請求處理管道,我覺得可以分兩個步驟來進行:首先,我們可以在忽略具體細節的前提下搞清楚管道處理HTTP請求的總體流程;在對總體流程有了大致瞭解之後,我們再來補充這些刻意忽略的細節。為了讓讀者... ...
  • 1、安裝環境 安裝.Net Core SDK 安裝VS2015 Update3 安裝DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe 2、新建Core工程 項目結構圖 3、運行 如果選擇IIS Express啟動方式,埠則隨機,如果選擇項目名稱運行預設埠 ...
  • 問題一:USB的傳輸線結構是如何的呢? 答案一:一條USB的傳輸線分別由地線、電源線、D+、D-四條線構成,D+和D-是差分輸入線,它使用的是3.3V的電壓(註意哦,與CMOS的5V電平不同),而電源線和地線可向設備提供5V電壓,最大電流為500MA(可以在編程中設置的,至於硬體的實現機制,就不要管 ...
  • 一、匿名函數lambda lambda argument1,argument2,...argumentN :expression using arguments 1、lambda是一個表達式,而不是一個語句。 因為這一點,lambda可以出現在python語法不允許def出現的地方 例如,在一個列表 ...
  • 對文件路徑的操作 os.path.split(p)函數返回一個路徑的目錄名和文件名。 os.path.splitext():分離文件名與擴展名 os.path.isfile()和os.path.isdir()函數分別檢驗給出的路徑是一個文件還是目錄。 os.path.isabs(path):判斷一個 ...
  • http://www.cnblogs.com/MnCu8261/p/5418632.html ...
  • os模塊提供了對目錄或者文件的新建/刪除/查看文件屬性,還提供了對文件以及目錄的路徑操作。比如說:絕對路徑,父目錄…… os.sep可以取代操作系統特定的路徑分隔符。windows下為 “\\”,Linux下為"/" os.linesep字元串給出當前平臺使用的行終止符。例如,Windows使用'\ ...
  • 今天來總結下python3.4版本字典的一些操作方法。 字典是Python裡面一種無序存儲結構,存儲的是鍵值對 key - value。關鍵字應該為不可變類型,如字元串、整數、包含不可變對象的元組。字典的創建很簡單,用 d = {key1 : value2, key2 : value2}的形式就可以 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...