【福祉記事】パイソンクロールガールマップ
ヒント:この記事は学習と参照のみを目的としています。体の面倒を見てください(手動でおもしろい)。
写真を始める
ps。透かしなしで使いやすいビデオ編集ツールがあることを知っている大男は誰ですか、それをお勧めします〜
Dididi ~~~ Mzituと
言えば、おそらく古い運転手がピットを知っているはずです。私は2日前にその存在を恥ずかしかったので、私は恥ずかしいです!それについての爬虫類は、無限、無限、そして上昇しているとも言えます。潮が下がる...トピックに戻り、ここでは主に私の計画をあなたと共有したいと思います。
1.シングルスレッドバージョン
Mzituのクロールについては、クライミングメカニズムがあまりないため、比較的初心者レベルである必要があります。現在の状況によると、2つの主要なポイントがあります。
- ヘッダー内のリファラーパラメーター:ソリューションも非常にシンプルです。このパラメーターをリクエストヘッダーに追加するだけで、動的に変更する必要はありません。ホームページアドレスとして修正できます。
- リクエストの速度制限:実際のクロールプロセスでは、クロール速度が速すぎるとIPがブロックされることが多く、適切に速度を制限するか、プロキシプールに参加するだけで済みます。
特定のクローラー分析、インターネットでのランダム検索は束です。ここにコードを直接提供します:
# =============================================================================
# Mzitu图片爬取
# =============================================================================
import re
import os
import time
import queue
import requests
from tqdm import tqdm
from termcolor import *
from colorama import init
# 解决CMD无法显示颜色问题
init(autoreset=False)
class spider_Mzidu():
def __init__(self):
# 定义请求地址
self.url_page = 'https://www.mzitu.com/page/%d/' # 搜索套图页面(用以获取套图ID)
self.url_taotu = 'https://www.mzitu.com/%s' # 套图页面(用以获取图片地址)
# 定义请求头
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
'Accept': '*/*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'X-Requested-With': 'XMLHttpRequest',
'Connection': 'keep-alive',
'Referer': 'https://www.mzitu.com',
}
# 定义正则表达式
self.p_id = '<span><a href="https://www.mzitu.com/(\d*?)" target="_blank">(.*?)</a></span>'
self.p_imgurl = '"main-image">.*?<img src="(.*?)"'
self.p_page = '…</span>.*?<span>(\d*?)</span>'
# 存储变量
self.queue_id = queue.Queue()
def getPages(self): # 获取总页数
res = requests.get(self.url_page%1,headers=self.headers)
html = res.text
N = re.findall('''class="page-numbers dots">[\s\S]*?>(\d*?)</a>[\s\S]*?"next page-numbers"''',html)[0]
return int(N)
def getID(self): # 获取套图ID
page_range = input('请输入爬取页数(如1-10):')
p_s = int(page_range.split('-')[0])
p_e = int(page_range.split('-')[1])
time.sleep(0.5)
print(colored('开始获取套图ID'.center(50,'-'),'green'))
bar = tqdm(range(p_s,p_e+1),ncols=60) # 进度条
for p in bar:
res = requests.get(self.url_page%p,headers=self.headers)
html = res.text
ids = re.findall(self.p_id,html)
for i in ids:
self.queue_id.put(i)
bar.set_description('第%d页'%p)
def downloadImg(self,imgurl): # 下载图片
res = requests.get(imgurl,headers=self.headers)
img = res.content
return img
def parseTaotu(self,taotuID): # 解析套图的"图片数量",以及"图片地址"
res = requests.get(self.url_taotu%taotuID,headers=self.headers)
html = res.text
page = int(re.findall(self.p_page,html)[0])
imgurl = re.findall(self.p_imgurl,html)[0]
imgurl = imgurl[:-6]+'%s'+imgurl[-4:]
return(imgurl,page)
def downloadTaotu(self): # 下载套图
while not self.queue_id.empty():
taotu = self.queue_id.get()
taotuID = taotu[0]
taotuName = taotu[1]
try:
imgurl,page = self.parseTaotu(taotuID)
path = '[P%d]'%page+taotuName
if not os.path.exists(path):
os.mkdir(path)
bar = tqdm(range(1,page+1),ncols=50) # 进度条
for i in bar:
url = imgurl%(str(i).zfill(2))
img = self.downloadImg(url)
with open('./%s/%d.jpg'%(path,i),'wb') as f:
f.write(img)
print('套图("'+colored(taotuName,'red')+'")爬取完成')
except:
time.sleep(3)
self.queue_id.put(taotu)
def run(self): # 主程序
os.system('cls') # 清空控制台
print('*'*35)
print('*'+'欢迎使用Mzitu下载器'.center(26)+'*')
print('*'*35)
N = self.getPages()
print(('Mzitu当前共有%s页!'%colored(N,'red')).center(30))
print('\n')
self.getID()
print('\n'+colored('开始爬取套图'.center(50,'-'),'green'))
self.downloadTaotu()
spider = spider_Mzidu()
spider.run()
第二に、マルチスレッドバージョン
「シングルスレッドはとても遅いですか?冗談ですか?我慢できませんか?」
ゲストの担当者、マルチスレッドバージョンを試してください。
# =============================================================================
# Mzitu图片爬取(多线程)
# =============================================================================
import re
import os
import time
import queue
import requests
import threading
from tqdm import tqdm
from termcolor import *
from colorama import init
# 解决CMD无法显示颜色问题
init(autoreset=False)
# 代理(XXX代理)
def Get_proxy():
res = requests.get('xxxxxxxxxxxxxxxxxxx')
html = res.text
return html
class spider_Mzidu():
def __init__(self):
# 定义请求地址
self.url_page = 'https://www.mzitu.com/page/%d/' # 搜索套图页面(用以获取套图ID)
self.url_taotu = 'https://www.mzitu.com/%s' # 套图页面(用以获取图片地址)
# 定义请求头
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
'Accept': '*/*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'X-Requested-With': 'XMLHttpRequest',
'Connection': 'keep-alive',
'Referer': 'https://www.mzitu.com',
}
# 定义正则表达式
self.p_id = '<span><a href="https://www.mzitu.com/(\d*?)" target="_blank">(.*?)</a></span>'
self.p_imgurl = '"main-image">.*?<img src="(.*?)"'
self.p_page = '…</span>.*?<span>(\d*?)</span>'
# 存储变量
self.queue_id = queue.Queue()
#HTTP代理
proxy = Get_proxy()
self.proxies = {'http':'http://'+proxy,
'https':'https://'+proxy}
def getPages(self): # 获取总页数
res = requests.get(self.url_page%1,headers=self.headers,proxies=self.proxies,timeout=10)
html = res.text
N = re.findall('''class="page-numbers dots">[\s\S]*?>(\d*?)</a>[\s\S]*?"next page-numbers"''',html)[0]
return int(N)
def getID(self): # 获取套图ID
page_range = input('请输入爬取页数(如1-10):')
p_s = int(page_range.split('-')[0])
p_e = int(page_range.split('-')[1])
time.sleep(0.5)
print(colored('开始获取套图ID'.center(50,'-'),'green'))
bar = tqdm(range(p_s,p_e+1),ncols=60) # 进度条
for p in bar:
res = requests.get(self.url_page%p,headers=self.headers,proxies=self.proxies,timeout=10)
html = res.text
ids = re.findall(self.p_id,html)
for i in ids:
self.queue_id.put(i)
bar.set_description('第%d页'%p)
def downloadImg(self,imgurl,proxies): # 下载图片
res = requests.get(imgurl,headers=self.headers,proxies=proxies,timeout=10)
img = res.content
return img
def parseTaotu(self,taotuID,proxies): # 解析套图的"图片数量",以及"图片地址"
res = requests.get(self.url_taotu%taotuID,headers=self.headers,proxies=proxies,timeout=10)
html = res.text
page = int(re.findall(self.p_page,html)[0])
imgurl = re.findall(self.p_imgurl,html)[0]
imgurl = imgurl[:-6]+'%s'+imgurl[-4:]
return(imgurl,page)
def downloadTaotu(self): # 下载套图
proxy = Get_proxy()
proxies = {'http':'http://'+proxy,
'https':'https://'+proxy}
while not self.queue_id.empty():
taotu = self.queue_id.get()
taotuID = taotu[0]
taotuName = taotu[1]
try:
imgurl,page = self.parseTaotu(taotuID,proxies)
path = '[P%d]'%page+taotuName
if not os.path.exists(path):
os.mkdir(path)
bar = tqdm(range(1,page+1),ncols=50) # 进度条
for i in bar:
url = imgurl%(str(i).zfill(2))
img = self.downloadImg(url,proxies)
with open('./%s/%d.jpg'%(path,i),'wb') as f:
f.write(img)
print('套图("'+colored(taotuName,'red')+'")爬取完成')
except:
time.sleep(3)
proxy = Get_proxy()
proxies = {'http':'http://'+proxy,
'https':'https://'+proxy}
self.queue_id.put(taotu)
def changeProxy(self): # 更换代理
proxy = Get_proxy()
self.proxies = {'http':'http://'+proxy,
'https':'https://'+proxy}
def run(self): # 主程序
os.system('cls') # 清空控制台
print('*'*35)
print('*'+'欢迎使用Mzitu下载器'.center(26)+'*')
print('*'*35)
N = self.getPages()
print(('Mzitu当前共有%s页!'%colored(N,'red')).center(30))
print('\n')
self.getID()
print('\n'+colored('开始爬取套图'.center(50,'-'),'green'))
# 多线程下载套图
N_thread = 3
thread_list = []
for i in range(N_thread):
thread_list.append(threading.Thread(target=self.downloadTaotu))
for t in thread_list:
t.start()
for t in thread_list:
t.join()
spider = spider_Mzidu()
spider.run()
これは注意深く発見する必要があります。実際、マルチスレッドバージョンとシングルスレッドバージョンの構造にはほとんど違いがありません(ここにもコードのアイデアがあり、元のコードを将来マルチスレッドに変更する場合に便利です。クイック)、主に次の2つのポイント:
- downloadTaotu()関数を呼び出すときは、スレッド化モジュールを使用してマルチスレッド化された複数の呼び出しを有効にします。
- HTTPプロキシモジュールを追加しました。ここでは、あなたの裁量でそれを維持するかどうかを検討できますが、私のテストによると、マルチスレッドを使用する場合は、引き続きプロキシに参加することをお勧めします。そうしないと、IPがブロックされる可能性があります。
最後に書く
コードの進行状況バーまたは出力テキストの色に興味がある場合は、コード出力をよりコケティッシュにするには、ここを参照してください。(Pythonのクールなカラー出力とプログレスバー印刷)
本文に不備がある場合は、批判して訂正してください。
最後に、お待ちいただき、ありがとうございます。