–
需要安装的库:
import urllib.request
from bs4 import BeautifulSoup
import re
from fontTools.ttLib import TTFont
import xlwt
过程中使用的部分软件:
-
正则表达式测试器
-
fontcreator
-
合适的OCR软件
记录操作步骤及代码如下所示:
1. 网页解析
1.1 爬取数据解析
选择餐饮店铺数量较多的上海万象城店,搜索结果界面如下:
-
每页显示15条数据,共10页内容
-
每条店铺信息包含内容如下:
店铺名称 | 是否提供团购/为分店/广告 |
星级、评分、评价人数、人均价格 | 口味、环境、服务 |
菜品种类、地址分区、详细地址 | |
推荐菜 | |
团购信息、优惠信息 |
1.2 网址解析
首页URL地址:http://www.dianping.com/search/keyword/1/10_%E4%B8%87%E8%B1%A1%E5%9F%8E](http://www.dianping.com/search/keyword/1/10_万象城)
第二页URL地址:http://www.dianping.com/search/keyword/1/10_%E4%B8%87%E8%B1%A1%E5%9F%8E/p2](http://www.dianping.com/search/keyword/1/10_万象城/p2)
第三页URL地址:http://www.dianping.com/search/keyword/1/10_%E4%B8%87%E8%B1%A1%E5%9F%8E/p3
建立循环:
for i in range(1,11)
baseURL = ‘http://www.dianping.com/search/keyword/1/10_%E4%B8%87%E8%B1%A1%E5%9F%8E/p’
URL = baseURL + str(i)
1.3 登陆处理
大众点评的网页翻页需要登陆。这里采用手机验证码的方式登陆,使用开发者工具提取cookie、User-Agent,打包为headers。
1.4 定义爬取函数askURL
def askURL(URL):
head = {“User-Agent”: “”, “cookie": “”}#保密原因,省略使用的User-Agent与Cookie
request = urllib.request.Request(URL, headers=head)
html = “”
html = urllib.request.urlopen(request).read().decode(‘utf-8’) #使用UTF-8解码
return (html)
2. 数据爬取与提取
2.1 数据爬取
循环调用askURL函数,爬取每页信息,储存在字符串变量html中
def getData(baseURL):
for i in range(1,10):
URL = baseURL + str(i)
html = askURL(URL)#html是askURL的返回结果,循环下的html记录单页的爬取结果,因此数据解析提取也需要在循环内进行
使用开发者工具读取源码,可以看到全部的店铺信息储存在ID为shop-list-all-list的div标签中,每个li标签为一条店铺记录。其中pic分类记录缩略图、txt分类记录店铺信息,svr-info记录团购信息
2.2 使用BeautifulSoup
方案1:提取多个标签,手动合并
soup = BeautifulSoup(html, “html.parser”)
soupfind = soup.find_all(‘div’, { ‘class’ :{“pic” , “txt” , “svr-info”}})#提取多个标签下信息时的处理方式,会提取为3个列表,需要手动合并为一个
#仅提取单个标签时的写法
soupfind = soup.find_all(‘div’, class_ :“txt” )
#合并过程(仅供参考)
soup_find = []
i = 0
while i < len(soupfind):
l = “”
l = str(soupfind[i]) + str(soupfind[i+1]) + str(soupfind[i+2])
soup_find.append(l)
i += 3
但后续操作中发现,部分店铺不含团购信息,导致”svr-info“class下面为空值,每三个合并出现错误
方案2:由于每个店铺的全部信息含在一个
- 标签下
-
def getData(baseURL):
for i in range(1, 11):
URL = baseURL + str(i)
html = askURL(URL)
soup = BeautifulSoup(html, “html.parser”)
soup_find = soup.find_all(‘li’, class_ = “”)
但这种方式会提取出一些非店铺的分支,会造成正则表达式搜索结构出现大量空值,带来混乱,关注到title与店铺信息间必然存在一一对应关系,后续将采用这一方法剔除非店铺分支。
2.3 正则表达式
全部信息的正则表达式提取如下:
for item in soup_find:
item = str(item)
imgsrc = re.findall(re.compile(r’data-src=“http(.*?)😕/(.*?).meituan.net/(.*?)”'), item) # 图片
title = re.findall(re.compile(r’
(.*?)
'), item) # 店名if title == []: #
- 标签会筛选出一些非店铺的分支,由于title是店铺信息一定含有的信息,使用title筛选,留下店铺信息
-
pass
else:
if imgsrc == []:
img = []
else:
img = [“http” + (imgsrc[0])[0] + “😕/” + (imgsrc[0])[1] + “.meituan.net/” + (imgsrc[0])[2]]
branch = re.findall(re.compile(r’分店’), item) # 分店
if branch == “分店”:
ifbranch = [“1”]
else:
ifbranch = [“0”]
if re.findall(re.compile(r’
(.*?)'), item) == []:star = []
score = []
else:
star = (re.findall(re.compile(r’
(.*?)'), item)[0])[0] # 星级
score = (re.findall(re.compile(r’
(.*?)'), item)[0])[1] # 评分
numraters = re.findall(re.compile(r’(.*?)\s*条评价'), item) # 评分人数
avgprice = re.findall(re.compile(r’人均\s*¥(.*?)'), item) # 人均价格
taste = re.findall(re.compile(r’口味(.*?)'), item) # 口味
enviro = re.findall(re.compile(r’环境(.*?)'), item) # 环境
serv = re.findall(re.compile(r’服务(.*?)'), item) # 服务
variety = re.findall(
re.compile(r’<a data-click-name=“shop_tag_cate_click”.*?">(.*?)'),
item) # 菜品种类
zone = re.findall(
re.compile(r’<a data-click-name=“shop_tag_region_click”.*?">(.*?)'),
item) # 地址分区
address = re.findall(re.compile(r’(.*?)\s*'), item) # 详细地址
recommend = re.findall(re.compile(
r’<a class=“recommend-click” data-click-name=“shop_tag_dish_click”.*?target=“_blank”>(.*?)'),
item) # 推荐菜
tg_info = re.findall(re.compile(
r’\s*团购:(.*?)\s*'),
item) # 团购信息
coupon = re.findall(re.compile(r’优惠:(.*?)\s*'), item) # 优惠信息
data = []
data.append(img)
data.append(title)
data.append(ifbranch)
data.append(star)
data.append(score)
data.append(numraters)
data.append(avgprice)
data.append(taste)
data.append(enviro)
data.append(serv)
data.append(variety)
data.append(zone)
data.append(address)
data.append(recommend)
data.append(tg_info)
data.append(coupon)
datalist.append(data)
提取结果:
[[‘http://p0.meituan.net/biztone/193986969_1624004529519.jpeg%40340w_255h_1e_1c_1l%7Cwatermark%3D0’], [‘桂满陇-锦绣江南(万象城店)’], [0], ‘45’, ‘4.66’, [‘\uec0e\ue10c1\uf819’], [‘\uec0e\ue498’], [‘\ue82c.\uf819\ue3b9’], [‘\ue82c.\uecd2\ue82c’], [‘\ue82c.\ue3b9\uf819’], [‘浙\ue913’], [‘\uf35e\ue12a\ueac9’], [‘吴\uf136\uf36b1599\uf75f\uea4c象\uf7d04\uf370402A\uf089\ue668’], [‘吮指鸡爪’, ‘石锅沃豆腐’, ‘公主素蟹粉’], [‘桂满陇·西湖船宴!仅售388元!价值454元的招牌必尝四人餐1份,提供免费WiFi。’], []
3. 字体反爬
3.1 字体反爬方式
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
ad5355a2c5eeff0.png)
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
[外链图片转存中…(img-nf0z5Hmj-1711815965908)]