前言
今天在群里有人派外包的其中一个是抓取大众点评的店铺信息,价格一千五,三天内完成!很多刚学编程的小伙伴,应该觉得这个一千五也太容易拿了,相对于大众点评这个网站,其实不是像爬小说,爬表情包那样容易的,大众点评这个网站它是有反爬的!其实也就两个点!
1.正则表达式撰写
2.破解字体反爬
这个网站难一点的就这两个地方!其他都和爬其他网站的思路基本差不多,如果有新手小伙伴的,那今天就跟小编一起来完成这个1500块钱的外包项目吧!
正文
需要安装的库:
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:由于每个店铺的全部信息含在一个<li>标签下
def getData(baseURL): for i in range(1, 11): URL = baseURL + str(i) html = askURL(URL) soup = BeautifulSoup(html, "html