本文已参与「新人创作礼」活动,一起开启掘金创作之路。
本次项目是将某网站的菜谱系列,做法与图片爬取下来,单独制作成docx文档
并与图片结合的形式,让我们看起来像是一张张菜谱,并利用数据可视化技术将内容展现出来,效果如下:
代码运行:
import re
from lxml import etree
from docx import Document
from docx.shared import Pt
from docx.shared import Inches
from docx.oxml.ns import qn
import os
import random
import requests
import pygal
headers = {
'user-agent': '自己的ua'}
title = []
num = 0
#分页爬取
for j in range(0,10):
urls = 'http://www.dxm.fit/m/product/search_j37v_p{}v.html'.format(j+1)
resp = requests.get(url = urls,headers=headers)
resp.encoding='utf-8'
html1 = resp.text
url = re.findall('<a href="(.*?)" class="a1">.*?</a>', html1)
for l in range(0,len(url)):
url = re.findall('<a href="(.*?)" class="a1">.*?</a>', html1)
url = 'http://www.dxm.fit/m/product/'+url[l]
response = requests.get(url=url, headers=headers)
response.encoding = 'utf-8'
html = response.text
et = etree.HTML(html)
tit = re.findall('<div class="tit box"><div class="d1 flex">(.*?)</div>',html)
pic = re.findall('<a href="#"><img class="img-responsive" src="(.*?)"',html)
# if('gif' not in pic[0]):
# print(tit,'',pic)
title.append(tit)
filename = 'D:\定时器\菜谱大全\图片\'
li=et.xpath("//div[@class='txtmain box']/div[@class='dmain flex']/article/p/text()")
li1 = et.xpath("//div[@class='dmain flex']/p/text()")
li2 = et.xpath("//div[@class='dmain flex']/section/section[@data-id='2230']/p/text()")
li3 = et.xpath("//div[@class='dmain flex']/p/span/text()")
nn = ""
ll = ""
kk_ = ""
kkk_ = ""
for i in li:
# i.replace(r"\u3000\u30001"," ")
# i.replace(r"\u3000\u30002", " ")
# i.replace(r"\u3000\u30003", " ")
# i.replace(r"\u3000\u30004", " ")
# i.replace(r"\u3000\u30005", " ")
nn+=i
if len(nn) != 0:
num+=1
for k in li1:
ll+=k
if len(ll) != 0:
num+=1
for kk in li2:
kk_ += kk
for kkk in li3:
kkk_ += kkk
# print(ll)
zong = ll+nn+kk_+kkk_
if not os.path.exists(filename):
os.mkdir(filename)
if ('gif' not in pic[0]):
name = pic[0].split('/')[-1]
response = requests.get(url=pic[0], headers=headers)
with open(filename + name, mode='wb') as f:
f.write(response.content)
doc1 = Document()
# 新增文档标题
doc1.add_heading(tit,0)
# 创建段落描述
# doc1.add_paragraph("{}".format(nn))
# 创建一级标题
if ('gif' not in pic[0]):
doc1.add_heading('图片展示',1)
doc1.add_picture(filename + name, width=Inches(5.5))
else:
doc1.add_paragraph('暂无图片')
# 创建段落描述
#
# doc1.add_paragraph("{}".format(zong))
#添加文档内容
paragraph = doc1.add_paragraph(nn)
# 设置中文字体
run = doc1.add_paragraph('这里设置中文字体:').add_run(zong)
run.font.name='黑体'
r = run._element
r.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
doc1.save('D:\定时器\菜谱大全{}.docx'.format(tit[0]))
print('爬取存储成功')
pic.clear()
tit.clear()
print('数量:',num)
# view = pygal.Pie()
#图表名
# view.title = '餐饮配方饼状图'
# for t_t in title:
# tu = random.randint(1,30)
# view.add('{}'.format(t_t),tu)
# # view.add('A', 31)
# # view.add('B', 55)
# # view.add('C', 14)
# #保存为view.svg(也可以保存为jpg)
# view.render_to_file('view.jpg')
# view.render_to_file('餐饮配方饼图.svg')
#柱形图
# view = pygal.Bar()
# #图表名
# view.title = '餐饮配方柱状图'
# #添加数据
#
# for t_t in title:
# ty = random.randint(1,25)
# view.add(t_t[0], [ty])
# #在浏览器中查看
# #view.render_in_browser()
# view.render_to_file('餐饮.svg')
技术原理:
首先伪装headers,获取到response后,解析成文本,通过xpath定位目标, 这里有个小技巧:
就是把源码复制到pycharm中,点击代码,选择重新格式化,然后就能看到层级关系了 ,这样方便我们定位,但是网站的代码并不固定,所以我添加了四种xpath定位 ,并且由于获取到的是列表,我们就用for循环将它们连接到一起,当然用函数也可以, 我加入了num计数,是为了方便观察爬取菜谱数,删了就行, pic我使用了re匹配,因为这个比较简单,但是主体内容因为放在了不同层级,你想用re匹配真的头大,所以用xpath比较方便,还有因为有的地方没有图片,所以储存是会报错的,因此,我加入了条件判断,没有就在docx文档上写暂无图片。
关于Word文档问题,我使用的是docx库,像 doc1.add_paragraph('添加文本'),操作比较简单,由于有大量文本,所以不选用Excel
最后是可视化,这里我用的是pygal,操作简单,视觉效果强,由于没有什么评价数和价格等数据,我就随便用标题当数据了,建议不要用饼图,数据太多,看不出来效果