寫(xiě)真集 --爬取腳本
@功能1:實(shí)現(xiàn)了反防盜鏈、翻頁(yè)、下載寫(xiě)真
@功能2:實(shí)現(xiàn)了文件的存儲(chǔ)、文件命名、文件的完整性
@功能3:實(shí)現(xiàn)了網(wǎng)絡(luò)異常捕獲反饋、日志功能、狀態(tài)進(jìn)度條
- 實(shí)際演示效果(本文章僅用于學(xué)習(xí)參考)

演示效果.png

日志數(shù)據(jù).png
@_@: 代碼寫(xiě)的比較爛希望大佬指出不足!!!
import time
import requests
import csv
import os
import datetime
import urllib.error
from lxml import etree
from tqdm import tqdm
# 注意必須要加Referer該網(wǎng)站有防盜鏈防盜鏈原理是依賴Referer來(lái)判斷的
headers = {
"Referer":"https://www.mzitu.com",
"User-Agent": "Mozilla/4.0 (Windows NT 11.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4430.85 Safari/537.36"
}
#======================================== Gte =================================================
def YEMA():
"""
@功能:實(shí)現(xiàn)獲取頁(yè)碼總數(shù)
:return: 返回?cái)?shù)值
"""
try:
url = 'https://www.mzitu.com/'
Session = requests.Session() # 使用Session()方法
GET_html = Session.get(url,headers=headers).text # 使用一個(gè)會(huì)話
get_xpath = etree.HTML(GET_html)
YeMian = get_xpath.xpath('/html/body/div[2]/div[1]/div[3]/div/a[4]/text()') # 獲取頁(yè)碼 屬性文本
return int(YeMian[0]) # 返回頁(yè)碼 轉(zhuǎn)換數(shù)據(jù)類型
except urllib.error.URLError: # 檢測(cè)網(wǎng)絡(luò)是否異常
print('抱歉,檢測(cè)到網(wǎng)絡(luò)異常錯(cuò)誤請(qǐng)稍后重試…… =_=!')
time.sleep(4)
quit()
# 創(chuàng)建日志
path_nome = f'寫(xiě)真數(shù)據(jù)'
if not os.path.exists(path_nome): # 檢測(cè)文件是否存在
print(os.mkdir(path_nome), "檢測(cè)到文件已丟失!--已重新創(chuàng)建") # 創(chuàng)建文件夾
with open('寫(xiě)真數(shù)據(jù)\\log.csv', 'a+', newline='', encoding='utf-8') as file_log: # 注意必須指定編碼newline=''參數(shù)為不空行
fieldnames = ['文案/標(biāo)題', '頁(yè)面鏈接', '下載狀態(tài)碼', '作品發(fā)布時(shí)間', '下載時(shí)間','文件狀態(tài)'] # 標(biāo)題
# DictWriter()方法初始化一個(gè)字典寫(xiě)入對(duì)象 該fieldnames參數(shù)用于字典
# 注意:key鍵必須和標(biāo)題一樣否則報(bào)錯(cuò)“ValueError: dict contains fields not in fieldnames:”
weiter = csv.DictWriter(file_log, fieldnames=fieldnames)
weiter.writeheader() # 將fieldnames寫(xiě)入標(biāo)題行
for yemian in range(YEMA()):
session = requests.Session() # 使用session()方法
url = f'https://www.mzitu.com/page/{1+yemian}/' # 拼接頁(yè)面的url
GET_html = session.get(url, headers=headers).text # 獲取文本
get_xpath = etree.HTML(GET_html) # 解析
for shu in range(24): # 一個(gè)主頁(yè)有25個(gè)作品
Meizi_int = get_xpath.xpath(f'//*[@id="pins"]/li[{shu+1}]/span[1]//a/@href') # 獲取作品鏈接 href屬于屬性
Meizi_nome = get_xpath.xpath(f'//*[@id="pins"]/li[{shu+1}]/span[1]/a/text()') # 獲取作品名稱 屬性文本
Meizi_time = get_xpath.xpath(f'//*[@id="pins"]/li[{shu+1}]/span[2]/text()') # 獲取發(fā)布日期 屬性文本
print('頁(yè)碼:',yemian + 1, Meizi_int, Meizi_nome, Meizi_time) # 打印
#========================================= Download ================================================
try:
get_Data = session.get(Meizi_int[0],headers=headers).text # 請(qǐng)求作品頁(yè)面
Data = etree.HTML(get_Data)
Data_ye = Data.xpath('/html/body/div[2]/div[1]/div[4]/a[5]/span/text()') # 圖片數(shù)量 屬性文本
data = Data_ye[0] # 收集圖片數(shù)量 去掉列表
bue = tqdm(range(int(data))) # 實(shí)例tqdm對(duì)象 歷遍圖片
for i_jpg in bue:
Download_url = Meizi_int[0]+'/'+str(i_jpg) # 拼接下載頁(yè)面鏈接
time.sleep(0.8) # 延時(shí)8毫秒
Download_get = session.get(Download_url,headers=headers).text # 請(qǐng)求下載頁(yè)面
Download_Data = etree.HTML(Download_get) # 解析
Data_jpg = Download_Data.xpath('/html/body/div[2]/div[1]/div[3]/p/a/img/@src') # 圖片url src屬于屬性 圖片的下載鏈接 # 作品下載鏈接
Download_jpg = session.get(Data_jpg[0],headers=headers) # 請(qǐng)求下載圖片
# print(Download_jpg)
#========================================= Path ================================================
nome_path = Meizi_nome[0] # 去掉列表
time_path = Meizi_time[0]
patn_file = f"寫(xiě)真數(shù)據(jù)\\{nome_path}" # 拼接成以標(biāo)題命名的文件夾
if not os.path.exists(patn_file): # 如果文件存在則不執(zhí)行如果不存在則執(zhí)行
os.mkdir(patn_file)
path_jpg = f'寫(xiě)真數(shù)據(jù)\\{nome_path}\\{i_jpg}_{time_path}.jpg' # 拼接以序號(hào)和發(fā)布日期命名的文件夾
True_False = os.path.exists(path_jpg) # 檢測(cè)文件的是否存在存在則輸出到進(jìn)度條
if True_False == False:
with open(path_jpg, 'wb') as flie_Download: # 以二進(jìn)制模式寫(xiě)入文件
flie_Download.write(Download_jpg.content) # 寫(xiě)入下載的二進(jìn)制數(shù)據(jù)(圖片)
State = 'Download……'
elif True_False == True:
State = '該文件已存在(掃描中)……'
#========================================= log ================================================
# 日志收集
log_url = Download_url # 頁(yè)面鏈接
log_200 = Download_jpg # 下載狀態(tài)碼
log_nome = nome_path # 文案/標(biāo)題
log_time = time_path # 發(fā)布時(shí)間
now = datetime.datetime.now()
log_time_i = now.strftime('%Y-%m-%d %H:%M:%S') # 當(dāng)前時(shí)間
cw = csv.writer(file_log) # 初始化寫(xiě)入對(duì)象
# 寫(xiě)入內(nèi)容
weiter.writerow({'文案/標(biāo)題':log_nome,'頁(yè)面鏈接':log_url,'下載狀態(tài)碼':log_200,
'作品發(fā)布時(shí)間':log_time,'下載時(shí)間':log_time_i,'文件狀態(tài)':State})
bue.set_description(f'{State}') # 進(jìn)度條標(biāo)題 狀態(tài)
except Exception as r: # 捕獲異常
print('未知錯(cuò)誤 %s' % (r)) # 打印異常
print('抱歉,程序發(fā)生異常請(qǐng)聯(lián)系開(kāi)發(fā)者…… =_=!')
time.sleep(10) # 維持命令行界面