概述
import requests
from lxml import etree
from openpyxl import Workbook
import re
from fontTools.ttLib import TTFont
headers = {
'Referer': 'https://www.dianping.com/',
'Host': 'www.dianping.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36',
'Cookie': '_lxsdk_cuid=17739884850c8-08129ef5936e95-c791e37-1fa400-17739884850c8; _lxsdk=17739884850c8-08129ef5936e95-c791e37-1fa400-17739884850c8; _hc.v=fe35843f-8279-52d3-458f-64e54125abce.1611577969; s_ViewType=10; ctu=739da695a9d02b38fdd5dae578f668f7e4a8f3bae960bc89c668a695a11598ff; fspop=test; cy=2; cye=beijing; _dp.ac.v=e7f567f9-8914-4d49-8c13-6887f3ecc32d; Hm_lvt_602b80cf8079ae6591966cc70a3940e7=1611579785,1611579860,1611579926,1611625175; _lx_utm=utm_source%3Dgoogle%26utm_medium%3Dorganic; lgtoken=04b8a9f65-d093-4552-b43c-794702bf7f2a; dper=366cef8b0805f224ae91f78bdaa38ea988f876e18f8d590df117472937f97f9baa67c3b6aef9021c6bb729ebf4dc54f33e34763203fe8443041257a84e16ad533f4c7343758cb35d76512d057ca50fcd35cf18ce034f379f8a61bcc73fcee662; ll=7fd06e815b796be3df069dec7836c3df; ua=17060343693; dplet=2fec7342bfb27e8228a5e7f40ff5f660; Hm_lpvt_602b80cf8079ae6591966cc70a3940e7=1611633877; _lxsdk_s=1773c5896c2-a3b-3f-658%7C%7C1088'
}
# proxy = {'http': 'http://' + requests.get('http://127.0.0.1:5000/get').text}
patten = re.compile(r'textLength="(.*?)"')
work = Workbook()
w = work.active
w.append(
['餐厅名称', '所处类别', '口味评分', '环境评分', '服务评分',
'人均消费', '餐厅营业时间', '总评分',
'评论总数', '餐厅位置信息', '评论者名字', '每条评论具体内容',
'评论的评论', '评论的浏览', '评论排序', '评论时间',
'评论打分(口味)', '评论人均消费', '是否有图片',
'评论者粉丝', '评论者关注', '评论获赞'])
# 获取svg文件及对应的字体css文件
url_svg = 'http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/08ef8d8f10080d81ae3ba79ac999e6b8.svg'
svg_resp = requests.get(url=url_svg).text
url_svg_p = 'http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/1ac4280822fdd2f06038703fc416045c.svg'
svg_resp_p = requests.get(url=url_svg_p).text
length = patten.findall(svg_resp)
url_css = 'http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/60790d2b8f057df9948765cda42316d4.css'
css_resp = requests.get(url=url_css).text
# 获取列表页中所有的店铺url及评分
def get_all_url():
start_urls = ['http://www.dianping.com/beijing/ch10/g101o2']
for url in start_urls:
response = requests.get(url=url, headers=headers).text
with open('2.html', 'w', encoding='utf-8') as f:
f.write(response)
html = etree.HTML(response)
url_list = html.xpath('//li[@class=""]/div[@class="pic"]/a/@href')[:5]
score_list = html.xpath('//div[@class="nebula_star"]/div[2]/text()')[:5]
return url_list, score_list
# 获取破解以后的页面
def gen_html(url_lst, score_list):
for i in range(len(url_lst)):
response = requests.get(url=url_lst[i] + f'/review_all', headers=headers).text
html = etree.HTML(response)
evaluate_number = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[1]/text()')[0].split('条')[0]
# 限制了评论的数量
if int(evaluate_number) >= 2000:
num = 150
else:
num = int(evaluate_number) // 15 + 1
for page in range(67, num):
review_url = url_lst[i] + f'/review_all/p{page}'
response = requests.get(url=review_url, headers=headers).text
html = etree.HTML(response)
# 替换页面中的字体加密
css_name_list = html.xpath('//svgmtsi/@class')
css = css_resp.replace('n', '').replace(' ', '')
p_css_name_list = html.xpath('//bb/@class')
p_css = css_resp.replace('n', '').replace(' ', '')
saveHtml_saveWoff(url_lst[i])
time_html = get_info()
response = trance_position(p_css_name_list, p_css, response)
response = trance_chart(css_name_list, css, response)
with open("4.html", "w", encoding="utf-8", errors="ignnore") as f:
f.write(response)
html = etree.HTML(response)
get_detail(html, time_html, score_list, i, page)
# 获取页面内容并存储
def get_detail(html, time_html, score_list, i, page):
# 获取页面内容
title = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[1]/h1/text()')[0]
# 评论的总量
evaluate_number = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[1]/text()')[0]
# 平均消费
avg = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[2]/text()')[0]
# 产品或者口味
product = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[3]/span[1]/text()')[0]
# 环境
et = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[3]/span[2]/text()')[0]
# 服务
fw = html.xpath('//*[@id="review-list"]/div[2]/div[1]/div[2]/span[3]/span[3]/text()')[0]
# 开业时间
open_time = ''.join(time_html.xpath('//p[@class="info info-indent"]/span//text()'))
# 评论的用户名
name_list = html.xpath('//a[@class="name"]/text()')
# 总评分
avg_score = score_list[i]
# 获取评论
element_list = [i.strip() for i in ''.join(
[i.strip('n').replace('n', '') for i in
html.xpath('//div[@class="review-words Hide"]/text()')]).split(
't')]
# 评论排序
sort = [str(i + (page - 1) * 15) for i in range(1, len(name_list) + 1)]
# 评论的时间
ev_time = html.xpath('//span[@class="time"]/text()')
# 评论的评分
ev_score = html.xpath('//span[@class="score"]/span[1]/text()')
# 评论的平均消费
ev_avg = html.xpath('//span[@class="score"]')
# 评论者url
evor_url_list = html.xpath('//a[@class="name"]/@href')
ev_list = []
for j in ev_avg:
if j.xpath('./span[5]/text()'):
j = j.xpath('./span[5]/text()')[0].strip().split(':')[1]
else:
j = '无'
ev_list.append(j)
review = html.xpath('//div[@class="main-review"]')
# 判断有没有图片
picture_list = []
for q in review:
is_picture = q.xpath('./div[@class="review-pictures"]/ul')
if is_picture:
q = '是'
else:
q = '否'
picture_list.append(q)
# 获取定位
position = ''.join(html.xpath('//div[@class="address-info"]/text()'))
# 处理评论者信息字体加密
k = 0
for j in range(len(name_list)):
if name_list[j].strip() == '匿名用户':
focus, fans, praise, read = ['无', '无', '无', '无']
else:
envor_url = 'http://www.dianping.com' + evor_url_list[k]
k += 1
# 评论者的关注,粉丝,点赞
focus, fans, praise = tran_envor(envor_url)
# 评论的浏览量
glance = ''.join(html.xpath(f'//em[@class="col-exp"][{j + 1}]/text()'))
# 需要存储的内容
message_list = [title, '本帮江泽菜', product.split(':')[1], et.split(':')[1], fw.split(':')[1],
avg.split(':')[1], open_time, avg_score,
evaluate_number.split('条')[0],
position.strip(), name_list[j].strip(), element_list[j],
glance.strip('(').strip(')'),
sort[j], ev_time[j], ev_score[j].strip().split(':')[1], ev_list[j], picture_list[j],
focus, fans,
praise]
w.append(message_list)
work.save('大众点评.xlsx')
# 处理位置字体加密,是(x,y)型的
def trance_position(p_css_name_list, p_css, response):
for p_css_name in p_css_name_list:
pattern = re.compile(r'.%s{background:-(d+).0px-(d+).0px;}' % p_css_name)
p_coord = pattern.findall(p_css)
if p_coord:
x, y = p_coord[0]
x, y = int(x), int(y)
y_patten = re.compile(r'y="(.*?)">')
y_list = y_patten.findall(svg_resp_p)
axis_y = [i for i in y_list if y <= int(i)][0]
chart_patten = re.compile(r'y="%s">(.*?)<' % axis_y)
chart = chart_patten.findall(svg_resp_p)[0][x // 14]
response = response.replace(f'<bb class="{p_css_name}"></bb>', chart)
return response
# 处理评论字体加密,是(id,text_length)型的
def trance_chart(css_name_list, css, response):
for css_name in css_name_list:
pattern = re.compile(r'.%s{background:-(d+).0px-(d+).0px;}' % css_name)
coord = pattern.findall(css)
if coord:
x, y = coord[0]
x, y = int(x), int(y)
num_patten = re.compile('id="(.*?)" d="M0 (.*?) H')
number_list = num_patten.findall(svg_resp)
axis_y = [(i, j) for i, j in number_list if y <= int(j)][0]
chart_patten = re.compile(r'href="#%s".*>(.*?)<' % axis_y[0])
chart = chart_patten.findall(svg_resp)[0][x // 14]
response = response.replace(f'<svgmtsi class="{css_name}"></svgmtsi>', chart)
response = response.replace(f'<bb class="{css_name}"></bb>', chart)
return response
# 处理营业时间woff文件字体加密
def saveHtml_saveWoff(i):
# 保存相应的html 和 此次的woff字体
url = i
res = requests.get(url=url, headers=headers).text
with open("1.html", "w", encoding="utf-8", errors="ignnore") as f:
f.write(res)
# 先抓取css,找到woff文件链接,保存字体
css_href_list = re.findall(r'href="(//s3plus.meituan.net/v1.{,100}?)"', res, re.S)
if css_href_list:
css_href = "http:" + css_href_list[0]
text = requests.get(css_href).text
# 营业时间中文字体
pos_woff_url = re.findall(r'(//s3plus.meituan.net/.{,100}?woff)', text)[1]
# 营业时间数字
hours_woff_url = re.findall(r'(//s3plus.meituan.net/.{,100}?woff)', text)[-1]
pos_content = requests.get("http:" + pos_woff_url).content
hours_content = requests.get("http:" + hours_woff_url).content
with open(f"pos.woff", "wb") as f:
f.write(pos_content)
with open('hours.woff', "wb") as f:
f.write(hours_content)
# 构建字体映射
def get_font_map(woff_file):
font = TTFont(woff_file)
font_names = font.getGlyphOrder()[2:]
# getGlyphOrder()方法返回所有字符编码名称,按表格顺序提取,类型为列表
woff_list = ['1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', '店', '中', '美', '家', '馆', '小', '车', '大',
'市', '公', '酒', '行', '国', '品', '发', '电', '金', '心',
'业', '商', '司', '超', '生', '装', '园', '场', '食', '有',
'新', '限', '天', '面', '工', '服', '海', '华', '水', '房',
'饰', '城', '乐', '汽', '香', '部', '利', '子', '老', '艺',
'花', '专', '东', '肉', '菜', '学', '福', '饭', '人', '百',
'餐', '茶', '务', '通', '味', '所', '山', '区', '门', '药',
'银', '农', '龙', '停', '尚', '安', '广', '鑫', '一', '容',
'动', '南', '具', '源', '兴', '鲜', '记', '时', '机', '烤',
'文', '康', '信', '果', '阳', '理', '锅', '宝', '达', '地',
'儿', '衣', '特', '产', '西', '批', '坊', '州', '牛', '佳',
'化', '五', '米', '修', '爱', '北', '养', '卖', '建', '材',
'三', '会', '鸡', '室', '红', '站', '德', '王', '光', '名',
'丽', '油', '院', '堂', '烧', '江', '社', '合', '星', '货',
'型', '村', '自', '科', '快', '便', '日', '民', '营', '和',
'活', '童', '明', '器', '烟', '育', '宾', '精', '屋', '经',
'居', '庄', '石', '顺', '林', '尔', '县', '手', '厅', '销',
'用', '好', '客', '火', '雅', '盛', '体', '旅', '之', '鞋',
'辣', '作', '粉', '包', '楼', '校', '鱼', '平', '彩', '上',
'吧', '保', '永', '万', '物', '教', '吃', '设', '医', '正',
'造', '丰', '健', '点', '汤', '网', '庆', '技', '斯', '洗',
'料', '配', '汇', '木', '缘', '加', '麻', '联', '卫', '川',
'泰', '色', '世', '方', '寓', '风', '幼', '羊', '烫', '来',
'高', '厂', '兰', '阿', '贝', '皮', '全', '女', '拉', '成',
'云', '维', '贸', '道', '术', '运', '都', '口', '博', '河',
'瑞', '宏', '京', '际', '路', '祥', '青', '镇', '厨', '培',
'力', '惠', '连', '马', '鸿', '钢', '训', '影', '甲', '助',
'窗', '布', '富', '牌', '头', '四', '多', '妆', '吉', '苑',
'沙', '恒', '隆', '春', '干', '饼', '氏', '里', '二', '管',
'诚', '制', '售', '嘉', '长', '轩', '杂', '副', '清', '计',
'黄', '讯', '太', '鸭', '号', '街', '交', '与', '叉', '附',
'近', '层', '旁', '对', '巷', '栋', '环', '省', '桥', '湖',
'段', '乡', '厦', '府', '铺', '内', '侧', '元', '购', '前',
'幢', '滨', '处', '向', '座', '下', '県', '凤', '港', '开',
'关', '景', '泉', '塘', '放', '昌', '线', '湾', '政', '步',
'宁', '解', '白', '田', '町', '溪', '十', '八', '古', '双',
'胜', '本', '单', '同', '九', '迎', '第', '台', '玉', '锦',
'底', '后', '七', '斜', '期', '武', '岭', '松', '角', '纪',
'朝', '峰', '六', '振', '珠', '局', '岗', '洲', '横', '边',
'济', '井', '办', '汉', '代', '临', '弄', '团', '外', '塔',
'杨', '铁', '浦', '字', '年', '岛', '陵', '原', '梅', '进',
'荣', '友', '虹', '央', '桂', '沿', '事', '津', '凯', '莲',
'丁', '秀', '柳', '集', '紫', '旗', '张', '谷', '的', '是',
'不', '了', '很', '还', '个', '也', '这', '我', '就', '在',
'以', '可', '到', '错', '没', '去', '过', '感', '次', '要',
'比', '觉', '看', '得', '说', '常', '真', '们', '但', '最',
'喜', '哈', '么', '别', '位', '能', '较', '境', '非', '为',
'欢', '然', '他', '挺', '着', '价', '那', '意', '种', '想',
'出', '员', '两', '推', '做', '排', '实', '分', '间', '甜',
'度', '起', '满', '给', '热', '完', '格', '荐', '喝', '等',
'其', '再', '几', '只', '现', '朋', '候', '样', '直', '而',
'买', '于', '般', '豆', '量', '选', '奶', '打', '每', '评',
'少', '算', '又', '因', '情', '找', '些', '份', '置', '适',
'什', '蛋', '师', '气', '你', '姐', '棒', '试', '总', '定',
'啊', '足', '级', '整', '带', '虾', '如', '态', '且', '尝',
'主', '话', '强', '当', '更', '板', '知', '己', '无', '酸',
'让', '入', '啦', '式', '笑', '赞', '片', '酱', '差', '像',
'提', '队', '走', '嫩', '才', '刚', '午', '接', '重', '串',
'回', '晚', '微', '周', '值', '费', '性', '桌', '拍', '跟',
'块', '调', '糕']
texts = woff_list
num_uni_dict = {}
for i, uni in enumerate(font_names):
num_uni_dict[uni.lower().replace('uni', '&#x') + ';'] = str(texts[i])
return num_uni_dict
# 替换
def get_info():
with open("1.html", "r", encoding="utf-8", errors="ignore") as f:
html = f.read()
hours_map_dict = get_font_map('hours.woff')
pos_map_dict = get_font_map('pos.woff')
for uni in hours_map_dict.keys():
html = html.replace(uni, hours_map_dict[uni])
for uni in pos_map_dict.keys():
html = html.replace(uni, pos_map_dict[uni])
parse_html = etree.HTML(html)
return parse_html
# 处理评论者信息字体woff文件加密
def tran_envor(i):
res = requests.get(url=i, headers=headers).text
with open("3.html", "w", encoding="utf-8", errors="ignnore") as f:
f.write(res)
css_href_list = re.findall(r'href="(//s3plus.meituan.net/v1.{,100}?)"', res, re.S)
if css_href_list:
css_href = "http:" + css_href_list[0]
text = requests.get(css_href).text
envor_woff_url = re.findall(r'(//s3plus.meituan.net/.{,100}?woff)', text)[-2]
pos_content = requests.get("http:" + envor_woff_url).content
with open("fans.woff", "wb") as f:
f.write(pos_content)
font = TTFont("fans.woff")
font_names = font.getGlyphOrder()[2:]
# getGlyphOrder()方法返回所有字符编码名称,按表格顺序提取,类型为列表
woff_list = ['1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', '店', '中', '美', '家', '馆', '小', '车', '大',
'市', '公', '酒', '行', '国', '品', '发', '电', '金', '心',
'业', '商', '司', '超', '生', '装', '园', '场', '食', '有',
'新', '限', '天', '面', '工', '服', '海', '华', '水', '房',
'饰', '城', '乐', '汽', '香', '部', '利', '子', '老', '艺',
'花', '专', '东', '肉', '菜', '学', '福', '饭', '人', '百',
'餐', '茶', '务', '通', '味', '所', '山', '区', '门', '药',
'银', '农', '龙', '停', '尚', '安', '广', '鑫', '一', '容',
'动', '南', '具', '源', '兴', '鲜', '记', '时', '机', '烤',
'文', '康', '信', '果', '阳', '理', '锅', '宝', '达', '地',
'儿', '衣', '特', '产', '西', '批', '坊', '州', '牛', '佳',
'化', '五', '米', '修', '爱', '北', '养', '卖', '建', '材',
'三', '会', '鸡', '室', '红', '站', '德', '王', '光', '名',
'丽', '油', '院', '堂', '烧', '江', '社', '合', '星', '货',
'型', '村', '自', '科', '快', '便', '日', '民', '营', '和',
'活', '童', '明', '器', '烟', '育', '宾', '精', '屋', '经',
'居', '庄', '石', '顺', '林', '尔', '县', '手', '厅', '销',
'用', '好', '客', '火', '雅', '盛', '体', '旅', '之', '鞋',
'辣', '作', '粉', '包', '楼', '校', '鱼', '平', '彩', '上',
'吧', '保', '永', '万', '物', '教', '吃', '设', '医', '正',
'造', '丰', '健', '点', '汤', '网', '庆', '技', '斯', '洗',
'料', '配', '汇', '木', '缘', '加', '麻', '联', '卫', '川',
'泰', '色', '世', '方', '寓', '风', '幼', '羊', '烫', '来',
'高', '厂', '兰', '阿', '贝', '皮', '全', '女', '拉', '成',
'云', '维', '贸', '道', '术', '运', '都', '口', '博', '河',
'瑞', '宏', '京', '际', '路', '祥', '青', '镇', '厨', '培',
'力', '惠', '连', '马', '鸿', '钢', '训', '影', '甲', '助',
'窗', '布', '富', '牌', '头', '四', '多', '妆', '吉', '苑',
'沙', '恒', '隆', '春', '干', '饼', '氏', '里', '二', '管',
'诚', '制', '售', '嘉', '长', '轩', '杂', '副', '清', '计',
'黄', '讯', '太', '鸭', '号', '街', '交', '与', '叉', '附',
'近', '层', '旁', '对', '巷', '栋', '环', '省', '桥', '湖',
'段', '乡', '厦', '府', '铺', '内', '侧', '元', '购', '前',
'幢', '滨', '处', '向', '座', '下', '県', '凤', '港', '开',
'关', '景', '泉', '塘', '放', '昌', '线', '湾', '政', '步',
'宁', '解', '白', '田', '町', '溪', '十', '八', '古', '双',
'胜', '本', '单', '同', '九', '迎', '第', '台', '玉', '锦',
'底', '后', '七', '斜', '期', '武', '岭', '松', '角', '纪',
'朝', '峰', '六', '振', '珠', '局', '岗', '洲', '横', '边',
'济', '井', '办', '汉', '代', '临', '弄', '团', '外', '塔',
'杨', '铁', '浦', '字', '年', '岛', '陵', '原', '梅', '进',
'荣', '友', '虹', '央', '桂', '沿', '事', '津', '凯', '莲',
'丁', '秀', '柳', '集', '紫', '旗', '张', '谷', '的', '是',
'不', '了', '很', '还', '个', '也', '这', '我', '就', '在',
'以', '可', '到', '错', '没', '去', '过', '感', '次', '要',
'比', '觉', '看', '得', '说', '常', '真', '们', '但', '最',
'喜', '哈', '么', '别', '位', '能', '较', '境', '非', '为',
'欢', '然', '他', '挺', '着', '价', '那', '意', '种', '想',
'出', '员', '两', '推', '做', '排', '实', '分', '间', '甜',
'度', '起', '满', '给', '热', '完', '格', '荐', '喝', '等',
'其', '再', '几', '只', '现', '朋', '候', '样', '直', '而',
'买', '于', '般', '豆', '量', '选', '奶', '打', '每', '评',
'少', '算', '又', '因', '情', '找', '些', '份', '置', '适',
'什', '蛋', '师', '气', '你', '姐', '棒', '试', '总', '定',
'啊', '足', '级', '整', '带', '虾', '如', '态', '且', '尝',
'主', '话', '强', '当', '更', '板', '知', '己', '无', '酸',
'让', '入', '啦', '式', '笑', '赞', '片', '酱', '差', '像',
'提', '队', '走', '嫩', '才', '刚', '午', '接', '重', '串',
'回', '晚', '微', '周', '值', '费', '性', '桌', '拍', '跟',
'块', '调', '糕']
texts = woff_list
num_uni_dict = {}
for i, uni in enumerate(font_names):
num_uni_dict[uni.lower().replace('uni', '&#x') + ';'] = str(texts[i])
with open("3.html", "r", encoding="utf-8", errors="ignore") as f:
html = f.read()
for uni in num_uni_dict.keys():
html = html.replace(uni, num_uni_dict[uni])
parse_html = etree.HTML(html)
focus = ''.join(parse_html.xpath('//div[@class="user_atten"]/ul/li[1]/a/strong//text()'))
fans = ''.join(parse_html.xpath('//div[@class="user_atten"]/ul/li[2]/a/strong//text()'))
praise = ''.join(parse_html.xpath('//div[@class="user_atten"]/ul/li[3]/strong//text()'))
return focus, fans, praise
if __name__ == '__main__':
pass
url_list, score_list = get_all_url()
gen_html(url_list, score_list)
最后
以上就是深情大神为你收集整理的爬取大众点评全字段的全部内容,希望文章能够帮你解决爬取大众点评全字段所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复