作者 | 李秋鍵
責(zé)編 | 晉兆雨
頭圖 | CSDN付費下載自視覺中國
在很多的公司項目中,常常有很多對office項目的比較機械化的操作,在這里就可以借助Python實現(xiàn)對office的合理排版。而這里我們就將借助海爾公司的出貨表爬取對應(yīng)圖片信息,并重新排版成為更加合理的Excel布局。
而今天我們這個項目是來自于實際生活中真實存在的處理事件。海爾在國外的員工常常要處理一些進出貨的表格統(tǒng)計,但是由于國外人很多不大精通漢字,故常常要通過給出的漢字在網(wǎng)上搜索圖片,然后復(fù)制到表格中以方便國外人能看懂是什么貨物,并加上拼音有助于理解。相對以往而言,由于貨物清單任務(wù)量很大,常常需要大量時間人力而且容易出錯,故我們這里設(shè)計了個程序使得這一項任務(wù)完全可以由電腦自動完成,不僅速度極快,而且不需要浪費人力和精力,提高了生產(chǎn)效率。
實驗前的準(zhǔn)備
其中海爾給出的貨物清單的Excel在4.xlsx中,數(shù)據(jù)如下:
代碼總體框架
整體的程序框架分為兩個重要部分。一個部分是用來爬取數(shù)據(jù),另一個用來排版成美觀的Excel。如下詳解:
1 爬取數(shù)據(jù)并保存
如download.py程序可見。
首先我們流程是從Excel讀取數(shù)據(jù)、然后借助百度圖庫搜索圖片,并爬取保存。
2 Excel排版和拼音注釋
如xls.py可見。根據(jù)下載下來的圖片和文字及其拼音保存排版。
第三方庫介紹
-
Xlrd庫:用來讀取和保存Excel表格,更方便讀取數(shù)據(jù)
-
Pypinyin庫:用來把漢字轉(zhuǎn)為拼音,這里我們需要將它準(zhǔn)成有音素的拼音
-
Xlsxwriter庫:用來讀取和保存Excel表格,其可以更好地保存格式
-
Requests庫:Requests 是用Python語言編寫,基于 urllib,采用 Apache2 Licensed 開源協(xié)議的 HTTP 庫。它比 urllib 更加方便,可以節(jié)約我們大量的工作,完全滿足 HTTP 測試需求。
-
Re庫:正則表達式匹配
-
Pillow庫:讀取圖片
-
Urllib庫:用來網(wǎng)絡(luò)爬蟲處理
-
Socket庫:數(shù)據(jù)包處理
-
Openpyx庫l:openpyxl是一款比較綜合的工具,不僅能夠同時讀取和修改Excel文檔,而且可以對Excel文件內(nèi)單元格進行詳細設(shè)置,包括單元格樣式等內(nèi)容,甚至還支持圖表插入、打印設(shè)置等內(nèi)容,使用openpyxl可以讀寫xltm, xltx, xlsm, xlsx等類型的文件,且可以處理數(shù)據(jù)量較大的Excel文件,跨平臺處理大量數(shù)據(jù)是其它模塊沒法相比的。因此,openpyxl成為處理Excel復(fù)雜問題的首選庫函數(shù)。在使用openpyxl前先要掌握三個對象,即:Workbook(工作簿)、Worksheet(工作表)和Cell(單元格,存儲具體的數(shù)據(jù)對象)三個對象。
-
Time庫:用來每次爬取數(shù)據(jù)的適當(dāng)延遲,以防止網(wǎng)站封掉ip。
-
Os模塊:用來本地文件和文件夾的讀取和生成等等。
代碼
在download程序中,首先是根據(jù)給出的Excel表讀取數(shù)據(jù),代碼如下:
首先是設(shè)置編碼格式和導(dǎo)入所要使用到的庫:
#encoding=utf-8
importxlrd
frompypinyin import lazy_pinyin,pinyin
importxlsxwriter
importrequests
import os
import re
from PILimport Image
importtime
fromurllib import request
fromurllib import error
importrandom
importsocket
接著設(shè)立文件名變量方便保存和讀取。設(shè)立爬蟲包的延遲時間為20s。
#改文件名的地方
excel_address="4.xlsx"
socket.setdefaulttimeout(20)
為了防止反爬的問題,設(shè)立請求頭
header ={'User-Agent': 'Mozilla/5.0 (windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml,like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
接著使用xlrd庫讀取Excel表格,按照列對象讀取數(shù)據(jù)
workbook= xlrd.open_workbook(excel_address)
sheet =workbook.sheet_by_name("Sheet1")
col0 =sheet.col_values(0) # 獲取第1列內(nèi)容,序號那一列
col1 =sheet.col_values(1)# 獲取第2列內(nèi)容,物資名稱那一列
col2=sheet.col_values(2)#獲取第3列內(nèi)容,型號規(guī)格那一列
col3=sheet.col_values(3)
col4=sheet.col_values(4)
col5=sheet.col_values(5)
使用lazy_pinyin函數(shù)將漢字轉(zhuǎn)為拼音,同時保留了音素并保存:
for i in col1:
i=lazy_pinyin(i)
txt=""
for w in i:
txt+=w+" "
yin.append(txt)
print(yin)
根據(jù)百度圖片搜索圖片并爬取保存。其中為了防止網(wǎng)
頁延遲等問題,通過多次嘗試爬取合適的圖片:
numm=
for i in range(len(col0)):
print("完成了"+str((i/len(col0))*100)+"%
判斷讀取到的數(shù)據(jù)是否是數(shù)字,因為其中有些數(shù)據(jù)是
空格等等多余的無效數(shù)據(jù):
if isinstance(col0[i],float):
numm.append(i)
t=col1[i]+col2[i]
print(t)
url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + t + '&ct=201326592&v=flip'
result = requests.get(url, headers=header)
pic_url = re.findall('"objURL":"(.*?)",', result.text, re.S)
num=1
for each in range(len(pic_url)):
print('正在下載第' + str(num) + '張圖片,圖片地址:' + str(pic_url[each]))
try:
pic = requests.get(pic_url[each], timeout=2,headers=header)
保存爬取下來的圖片至對應(yīng)的文件夾中,文件夾名為
對應(yīng)行的序號。然后設(shè)置爬取下來的圖片尺寸為300
并保存:
if not os.path.exists("image/"+str(i)):
os.makedirs("image/"+str(i))
dir = "image/"+str(i)+"/" + str(num) + '.jpg'
fp = open(dir, 'wb')
fp.write(pic.content)
fp.close
try:
img = Image.open("image/" +str(i)+"/" + str(num) + '.jpg')
img.resize((300, 300)).save("image/" +str(i)+"/" + str(num) + '.jpg')
except:
pass
num += 1
if num == 5:
print("下一個。")
result.close
break
except :
print('【換資源中。。。】')
continue
每個貨物名稱只需要下載爬取四個圖片即可:
if num == 5:
print("下一個。")
result.close
time.sleep(random.randint(0,3))
break
其中download.py運行效果如下:
爬取下來的保存部分圖片如下:
接著使用xls.py進行排版。因為這里我們使用xlrd排版
時發(fā)現(xiàn)保存的Excel格式都失效了,故需要借助
openpyxl庫進行原有格式的保存和處理,即保存為
新的Excel為8.xlsx。
import os
import xlrd
from pypinyin import lazy_pinyin,pinyin
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
#改文件名的地方
excel_address="4.xlsx"
wb = load_workbook(excel_address)
wb.save("8.xlsx")
workbook = xlrd.open_workbook(excel_address)
sheet1 = workbook.sheet_by_name("Sheet1")
wb = load_workbook('8.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')
sht = wb.worksheets[0]
col0 = sheet1.col_values(0) #獲取第1列內(nèi)容,序號那一列
col1 = sheet1.col_values(1)#獲取第2列內(nèi)容,物資名稱那一列
col2=sheet1.col_values(2)#獲取第3列內(nèi)容,型號規(guī)格那一列
col3=sheet1.col_values(3)
col4=sheet1.col_values(4)
col5=sheet1.col_values(5)
根據(jù)Excel表格單元填充進拼音:
for i in range(len(col0)):
sht.row_dimensions[i].height = 150.0
if isinstance(col0[i], float):
sheet["G"+str(i+1)].value=yin[i]
接著根據(jù)已經(jīng)保存下來的爬取到的圖片依次按照布局
順序進行填充,同時還要設(shè)定一定的圖片尺寸,以保
證布局的美觀和合理:
for i in os.listdir("image"):
for j in os.listdir("image/"+i):
tw="image/"+i+"/"+j
label=j.split(".")
label=label[0]
根據(jù)label對象的數(shù)據(jù)判斷對應(yīng)序號,根據(jù)序號判斷對
應(yīng)圖片存放的文件夾位置,然后讀取圖片并復(fù)制到
Excel表格中:
if int(label)==1:
try:
img_address_2 = "image/" +i+"/"+ str(label) + '.jpg'
使用openpyxl中的image函數(shù)讀取圖片
img = Image(img_address_2)
設(shè)置圖片的長寬為200,統(tǒng)一尺寸以方便布局
img.width = 200.0
img.height = 200.0
通過單元格添加圖片即可達到插入圖片的效果
sht.add_image(img, 'J'+str(int(i)+1))
如果沒有合理的找到對應(yīng)圖片就跳過:
except:
pass
if int(label)==2:
try:
img_address_2 = "image/" +i+"/"+ str(label) + '.jpg'
img = Image(img_address_2)
img.width = 200.0
img.height = 200.0
sht.add_image(img, 'M'+str(int(i)+1))
except:
pass
if int(label)==3:
try:
img_address_2 = "image/" +i+"/"+ str(label) + '.jpg'
img = Image(img_address_2)
img.width = 200.0
img.height = 200.0
sht.add_image(img, 'P'+str(int(i)+1))
except:
pass
if int(label)==4:
try:
img_address_2 = "image/" +i+"/"+ str(label) + '.jpg'
img = Image(img_address_2)
img.width = 200.0
img.height = 200.0
sht.add_image(img, 'S'+str(int(i)+1))
except:
pass
wb.save("dels.xlsx")
最終得到的排版程序如下可見:
由此可見通過python的office操作和網(wǎng)絡(luò)搜索自動爬
取排版可以極大地節(jié)省人力和時間。
作者介紹:
李秋鍵,CSDN 博客專家,CSDN達人課作者。碩士在讀于中國礦業(yè)大學(xué),開發(fā)有taptapAndroid/ target=_blank class=infotextkey>安卓武俠游戲一部,vip視頻解析,文意轉(zhuǎn)換工具,寫作機器人等項目,發(fā)表論文若干,多次高數(shù)競賽獲獎等等。
源碼地址:
鏈接:
https://pan.baidu.com/s/1Rtl3zoQRhKeRstgnl1firw
提取碼:wk2z