日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python爬虫爬图片教程_Python爬虫入门教程 5-100 27270图片爬取

發布時間:2025/6/17 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python爬虫爬图片教程_Python爬虫入门教程 5-100 27270图片爬取 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

獲取待爬取頁面

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

為了以后的網絡請求操作方向,我們這次簡單的進行一些代碼的封裝操作。

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

pip install retrying

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

在這里我使用了一個隨機產生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

在這里,我希望網絡請求模塊嘗試3次之后,在報錯!

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

__retrying_requests 方法為私有方法,其中根據get和post方式進行邏輯判斷

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

網絡請求的方法已經聲明完畢,并且返回 response.content 數據流

下面基于這個私有方法,增加一個獲取網絡文本的方法和一個獲取網絡文件的方法。同步完善類的初始化方法,在開發中發現,我們要爬取的網頁編碼是gb2312 所以還需要給某些方法增加一個編碼參數

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

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

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

首先,創建一個 ImageList 類,這個類第一件事情,需要獲取我們爬取頁面的總頁碼數目

這個步驟比較簡單

獲取網頁源碼

正則匹配末頁元素

提取數字

import http_help as hh # 這個http_help 是我上面寫到的那個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

# 正則表達式匹配末頁,分析頁碼

def get_page_count(self):

# 注意這個地方需要傳入編碼

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方法,該方法已經獲取到了末尾的頁碼

我們在run方法內部,通過一個列表生成器

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

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

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

我們采用生產者和消費者模型,就是一個抓取鏈接圖片,一個下載圖片,采用多線程的方式進行操作,需要首先引入

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里面最后一個url,并且刪除

urls_lock.release() # 解鎖

print("正在操作{}".format(last_url))

content = self.__res.get_content(last_url,"gb2312") # 頁面注意編碼是gb2312其他格式報錯

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("所有鏈接已經運行完畢")

break

def get_page_list(self,content):

# 正則表達式

pattern = re.compile('

.*?')

list_page = re.findall(pattern, content)

return list_page

上述代碼中比較重要的有

threading.Lock() 鎖的使用,在多個線程之間操作全局變量,需要進行及時的鎖定;

其他的注意內容,我已經添加在注釋里面,只要你按著步驟一點點的寫,并且加入一些自己微妙的理解,就可以搞定。

到現在為止,我們已經抓取到了所有的圖片地址,我把他存放在了一個全局的變量里面 imgs_start_urls

那么現在又來了

這個列表里面存放的是 http://www.27270.com/ent/meinvtupian/2018/298392.html 這樣的地址,當你打開這個頁面之后,你會發現只有一張圖片 ,并且下面有個分頁。

點擊分頁之后,就知道規律了

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

....

當你進行多次嘗試之后,你會發現,后面的鏈接完全可以靠拼接完成,如果沒有這個頁面,那么他會顯示?

好了,如果你進行了上面的操作,你應該知道接下來怎么實現啦!

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

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)

# 判斷目錄是否存在,存在創建

if not os.path.exists(file_path):

os.mkdir(file_path) # 創建目錄

if os.path.exists("./downs/{}/{}".format(filder,filename)):

return

else:

try:

# 這個地方host設置是個坑,因為圖片為了防止盜鏈,存放在另一個服務器上面

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項

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(".")] # 字符串可以當成列表進行切片操作

while True:

img_url ="{}_{}.html".format(base_url,start_index) # url拼接

content = self.__res.get_content(img_url,charset="gbk") # 這個地方獲取內容,采用了gbk編碼

if content is not None:

pattern = re.compile('

[\s\S.]*?img alt="(.*?)".*? src="(.*?)" />')

# 匹配圖片,匹配不到就代表本次操作已經完畢

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 # 終止循環體

else:

print("{}鏈接加載失敗".format(img_url))

if imgs_lock.acquire(): # 鎖定

imgs_start_urls.append(img_url)

imgs_lock.release() # 解鎖

start_index+=1 # 上文描述中,這個地方需要不斷進行+1操作

所有的代碼都在上面了,關鍵的地方我盡量加上了標注,你可以細細的看一下,實在看不明白,就多敲幾遍,因為沒有特別復雜的地方,好多都是邏輯。

最后附上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()

一會過后,就慢慢收圖吧

總結

以上是生活随笔為你收集整理的python爬虫爬图片教程_Python爬虫入门教程 5-100 27270图片爬取的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。