国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python爬蟲入門教程 5-100 27270圖片爬取

wenhai.he / 2468人閱讀

摘要:為了以后的網(wǎng)絡(luò)請求操作方向,我們這次簡單的進(jìn)行一些代碼的封裝操作。接下來,就是比較重要的爬蟲代碼部分了。這一次,我們可以簡單的使用一下類和對象,并且加上簡單的多線程操作。最后附上部分的代碼,讓我們的代碼跑起來一會(huì)過后,就慢慢收圖吧

獲取待爬取頁面

今天繼續(xù)爬取一個(gè)網(wǎng)站,http://www.27270.com/ent/meinvtupian/ 這個(gè)網(wǎng)站具備反爬,so我們下載的代碼有些地方處理的也不是很到位,大家重點(diǎn)學(xué)習(xí)思路,有啥建議可以在評論的地方跟我說說。

為了以后的網(wǎng)絡(luò)請求操作方向,我們這次簡單的進(jìn)行一些代碼的封裝操作。

在這里你可以先去安裝一個(gè)叫做 retrying 的模塊

pip install retrying

這個(gè)模塊的具體使用,自己去百度吧。嘿嘿噠~

在這里我使用了一個(gè)隨機(jī)產(chǎn)生user_agent的方法

import requests
from retrying import retry
import random
import datetime

class R:

    def __init__(self,method="get",params=None,headers=None,cookies=None):
        # do something


    def get_headers(self):
        user_agent_list = [ 
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1" 
            "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", 
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", 
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", 
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", 
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", 
            "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", 
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", 
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", 
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", 
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", 
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
        ]
        UserAgent = random.choice(user_agent_list)
        headers = {"User-Agent": UserAgent}
        return headers
    #other code

retrying 最簡單的使用就是給你想不斷重試的方法加上 裝飾器 @retry

在這里,我希望網(wǎng)絡(luò)請求模塊嘗試3次之后,在報(bào)錯(cuò)!

同時(shí)在R類初始化方法中增加一些必備的參數(shù),你可以直接看下面的代碼

__retrying_requests 方法為私有方法,其中根據(jù)getpost方式進(jìn)行邏輯判斷

import requests
from retrying import retry
import random
import datetime

class R:

    def __init__(self,method="get",params=None,headers=None,cookies=None):
        #do something

    def get_headers(self):
        # do something
    @retry(stop_max_attempt_number=3)
    def __retrying_requests(self,url):
        if self.__method == "get":
            response = requests.get(url,headers=self.__headers,cookies=self.__cookies,timeout=3)
        else:
            response = requests.post(url,params=self.__params,headers=self.__headers,cookies=self.__cookies,timeout=3)
        return response.content

   
    # other code

網(wǎng)絡(luò)請求的方法已經(jīng)聲明完畢,并且返回 response.content 數(shù)據(jù)流

下面基于這個(gè)私有方法,增加一個(gè)獲取網(wǎng)絡(luò)文本的方法和一個(gè)獲取網(wǎng)絡(luò)文件的方法。同步完善類的初始化方法,在開發(fā)中發(fā)現(xiàn),我們要爬取的網(wǎng)頁編碼是gb2312 所以還需要給某些方法增加一個(gè)編碼參數(shù)

import requests
from retrying import retry
import random
import datetime

class R:
    # 類的初始化方法
    def __init__(self,method="get",params=None,headers=None,cookies=None):
        self.__method = method
        myheaders = self.get_headers()
        if headers is not None:
            myheaders.update(headers)
        self.__headers = myheaders
        self.__cookies = cookies
        self.__params = params


    def get_headers(self):
       # do something

    @retry(stop_max_attempt_number=3)
    def __retrying_requests(self,url):
        # do something

    # get請求
    def get_content(self,url,charset="utf-8"):
        try:
            html_str = self.__retrying_requests(url).decode(charset)
        except:
            html_str = None
        return html_str

    def get_file(self,file_url):
        try:
            file = self.__retrying_requests(file_url)
        except:
            file = None
        return file

到此,這個(gè)R類已經(jīng)被我們完善了,完整的代碼,你應(yīng)該從上面拼湊起來,你也可以直接翻到文章最后面,去github上直接查閱。

接下來,就是比較重要的爬蟲代碼部分了。這一次,我們可以簡單的使用一下類和對象,并且加上簡單的多線程操作。

首先,創(chuàng)建一個(gè) ImageList 類,這個(gè)類第一件事情,需要獲取我們爬取頁面的總頁碼數(shù)目

這個(gè)步驟比較簡單

獲取網(wǎng)頁源碼

正則匹配末頁元素

提取數(shù)字

import http_help as hh   # 這個(gè)http_help 是我上面寫到的那個(gè)R類
import re
import threading
import time
import os
import requests

# 獲取所有待爬取的URL列表
class ImageList():
    def __init__(self):
        self.__start = "http://www.27270.com/ent/meinvtupian/list_11_{}.html"  # URL模板
        # 頭文件
        self.__headers = {"Referer":"http://www.27270.com/ent/meinvtupian/",
                          "Host":"www.27270.com"
                          }
        self.__res = hh.R(headers=self.__headers)  # 初始化訪問請求
    def run(self):
        page_count =  int(self.get_page_count())

        if page_count==0:
            return
        urls = [self.__start.format(i) for i in range(1,page_count)]
        return urls


    # 正則表達(dá)式匹配末頁,分析頁碼
    def get_page_count(self):
        # 注意這個(gè)地方需要傳入編碼
        content = self.__res.get_content(self.__start.format("1"),"gb2312")
        pattern = re.compile("
  • 末頁
  • ") search_text = pattern.search(content) if search_text is not None: count = search_text.group(1) return count else: return 0 if __name__ == "__main__": img = ImageList() urls = img.run()

    上面的代碼注意get_page_count方法,該方法已經(jīng)獲取到了末尾的頁碼

    我們在run方法內(nèi)部,通過一個(gè)列表生成器

    urls = [self.__start.format(i) for i in range(1,page_count)]
    

    批量把要爬取的所有鏈接都生成完畢。

    分析上面爬取到的URL列表,捕獲詳情頁

    我們采用生產(chǎn)者和消費(fèi)者模型,就是一個(gè)抓取鏈接圖片,一個(gè)下載圖片,采用多線程的方式進(jìn)行操作,需要首先引入

    import threading
    import time

    完整代碼如下

    import http_help as hh
    import re
    import threading
    import time
    import os
    import requests
    
    urls_lock = threading.Lock()  #url操作鎖
    imgs_lock = threading.Lock()  #圖片操作鎖
    
    imgs_start_urls = []
    
    
    class Product(threading.Thread):
        # 類的初始化方法
        def __init__(self,urls):
            threading.Thread.__init__(self)
            self.__urls = urls
            self.__headers = {"Referer":"http://www.27270.com/ent/meinvtupian/",
                              "Host":"www.27270.com"
                              }
    
            self.__res = hh.R(headers=self.__headers)
    
        # 鏈接抓取失敗之后重新加入urls列表中
        def add_fail_url(self,url):
            print("{}該URL抓取失敗".format(url))
            global urls_lock
            if urls_lock.acquire():
                self.__urls.insert(0, url)
                urls_lock.release()  # 解鎖
        
        # 線程主要方法
        def run(self):
            print("*"*100)
            while True:
                global urls_lock,imgs_start_urls
                if len(self.__urls)>0:
                    if urls_lock.acquire():   # 鎖定
                        last_url = self.__urls.pop()   # 獲取urls里面最后一個(gè)url,并且刪除
                        urls_lock.release()  # 解鎖
    
                    print("正在操作{}".format(last_url))
    
                    content = self.__res.get_content(last_url,"gb2312")   # 頁面注意編碼是gb2312其他格式報(bào)錯(cuò)
                    if content is not  None:
                        html = self.get_page_list(content)
    
                        if len(html) == 0:
                            self.add_fail_url(last_url)
                        else:
                            if imgs_lock.acquire():
                                imgs_start_urls.extend(html)    # 爬取到圖片之后,把他放在待下載的圖片列表里面
                                imgs_lock.release()
    
                        time.sleep(5)
                    else:
                        self.add_fail_url(last_url)
    
                else:
                    print("所有鏈接已經(jīng)運(yùn)行完畢")
                    break
    
    
    
    
    
        def get_page_list(self,content):
            # 正則表達(dá)式
            pattern = re.compile("
  • .*?
  • ") list_page = re.findall(pattern, content) return list_page

    上述代碼中比較重要的有
    threading.Lock() 鎖的使用,在多個(gè)線程之間操作全局變量,需要進(jìn)行及時(shí)的鎖定;
    其他的注意內(nèi)容,我已經(jīng)添加在注釋里面,只要你按著步驟一點(diǎn)點(diǎn)的寫,并且加入一些自己微妙的理解,就可以搞定。

    到現(xiàn)在為止,我們已經(jīng)抓取到了所有的圖片地址,我把他存放在了一個(gè)全局的變量里面 imgs_start_urls
    那么現(xiàn)在又來了

    這個(gè)列表里面存放的是 http://www.27270.com/ent/meinvtupian/2018/298392.html 這樣的地址,當(dāng)你打開這個(gè)頁面之后,你會(huì)發(fā)現(xiàn)只有一張圖片 ,并且下面有個(gè)分頁。

    點(diǎn)擊分頁之后,就知道規(guī)律了

    http://www.27270.com/ent/meinvtupian/2018/298392.html 
    http://www.27270.com/ent/meinvtupian/2018/298392_2.html 
    http://www.27270.com/ent/meinvtupian/2018/298392_3.html 
    http://www.27270.com/ent/meinvtupian/2018/298392_4.html 
    ....

    當(dāng)你進(jìn)行多次嘗試之后,你會(huì)發(fā)現(xiàn),后面的鏈接完全可以靠拼接完成,如果沒有這個(gè)頁面,那么他會(huì)顯示?

    好了,如果你進(jìn)行了上面的操作,你應(yīng)該知道接下來怎么實(shí)現(xiàn)啦!

    我把所有的代碼,都直接貼在下面,還是用注釋的方式給大家把最重要的地方標(biāo)注出來

    class Consumer(threading.Thread):
        # 初始化
        def __init__(self):
            threading.Thread.__init__(self)
            self.__headers = {"Referer": "http://www.27270.com/ent/meinvtupian/",
                              "Host": "www.27270.com"}
            self.__res = hh.R(headers=self.__headers)
    
        # 圖片下載方法
        def download_img(self,filder,img_down_url,filename):
            file_path = "./downs/{}".format(filder)
            
            # 判斷目錄是否存在,存在創(chuàng)建
            if not os.path.exists(file_path):
                os.mkdir(file_path)  # 創(chuàng)建目錄
    
            if os.path.exists("./downs/{}/{}".format(filder,filename)):
                return
            else:
                try:
                    # 這個(gè)地方host設(shè)置是個(gè)坑,因?yàn)閳D片為了防止盜鏈,存放在另一個(gè)服務(wù)器上面
                    img = requests.get(img_down_url,headers={"Host":"t2.hddhhn.com"},timeout=3)
                except Exception as e:
                    print(e)
    
                print("{}寫入圖片".format(img_down_url))
                try:
                    # 圖片寫入不在贅述
                    with open("./downs/{}/{}".format(filder,filename),"wb+") as f:
                        f.write(img.content)
                except Exception as e:
                    print(e)
                    return
    
    
    
    
    
        def run(self):
    
            while True:
                global imgs_start_urls,imgs_lock
    
                if len(imgs_start_urls)>0:
                    if imgs_lock.acquire():  # 鎖定
                        img_url = imgs_start_urls[0]   #獲取到鏈接之后
                        del imgs_start_urls[0]  # 刪掉第0項(xiàng)
                        imgs_lock.release()  # 解鎖
                else:
                    continue
    
                # http://www.27270.com/ent/meinvtupian/2018/295631_1.html
    
                #print("圖片開始下載")
                img_url = img_url[0]
                start_index = 1
                base_url = img_url[0:img_url.rindex(".")]    # 字符串可以當(dāng)成列表進(jìn)行切片操作
    
                while True:
    
                    img_url ="{}_{}.html".format(base_url,start_index)   # url拼接
                    content = self.__res.get_content(img_url,charset="gbk")   # 這個(gè)地方獲取內(nèi)容,采用了gbk編碼
                    if content is not None:
                        pattern = re.compile("
    [sS.]*?img alt="(.*?)".*? src="(.*?)" />") # 匹配圖片,匹配不到就代表本次操作已經(jīng)完畢 img_down_url = pattern.search(content) # 獲取到了圖片地址 if img_down_url is not None: filder = img_down_url.group(1) img_down_url = img_down_url.group(2) filename = img_down_url[img_down_url.rindex("/")+1:] self.download_img(filder,img_down_url,filename) #下載圖片 else: print("-"*100) print(content) break # 終止循環(huán)體 else: print("{}鏈接加載失敗".format(img_url)) if imgs_lock.acquire(): # 鎖定 imgs_start_urls.append(img_url) imgs_lock.release() # 解鎖 start_index+=1 # 上文描述中,這個(gè)地方需要不斷進(jìn)行+1操作

    所有的代碼都在上面了,關(guān)鍵的地方我盡量加上了標(biāo)注,你可以細(xì)細(xì)的看一下,實(shí)在看不明白,就多敲幾遍,因?yàn)闆]有特別復(fù)雜的地方,好多都是邏輯。

    最后附上main部分的代碼,讓我們的代碼跑起來

    if __name__ == "__main__":
    
        img = ImageList()
        urls = img.run()
        for i in range(1,2):
            p = Product(urls)
            p.start()
    
        for i in range(1,2):
            c = Consumer()
            c.start()
    

    一會(huì)過后,就慢慢收圖吧

    文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/43875.html

    相關(guān)文章

    • Python爬蟲入門教程 5-100 27270圖片爬取

      摘要:為了以后的網(wǎng)絡(luò)請求操作方向,我們這次簡單的進(jìn)行一些代碼的封裝操作。接下來,就是比較重要的爬蟲代碼部分了。這一次,我們可以簡單的使用一下類和對象,并且加上簡單的多線程操作。最后附上部分的代碼,讓我們的代碼跑起來一會(huì)過后,就慢慢收圖吧 獲取待爬取頁面 今天繼續(xù)爬取一個(gè)網(wǎng)站,http://www.27270.com/ent/meinvtupian/ 這個(gè)網(wǎng)站具備反爬,so我們下載的代碼有...

      haitiancoder 評論0 收藏0

    發(fā)表評論

    0條評論

    最新活動(dòng)
    閱讀需要支付1元查看
    <