分享

手把手用Python网络爬虫带你爬取全国著名高校附近酒店评论

本帖最后由 阿飞 于 2020-2-25 21:59 编辑

问题导读
1.Python网络爬虫实现分为哪三步?
2.如何抓取没加酒店点评信息?
3.实现过程中遇到了哪些问题?


1 前言
  简介:本文介绍如何用python爬取全国著名高校附近的酒店点评,并进行分析,带大家看看著名高校附近的酒店怎么样。

2 具体实现
具体的实现主要是分为三步,具体的操作过程如下。

一、抓取高校附近的酒店信息
   由于电脑客户端的美团酒店没有评论信息,于是我从手机端的网页入手,网页地址为:https://i.meituan.com/awp/h5/hotel/search/search.html

  通过搜索北京大学附近的酒店,抓包找到了返回酒店json信息的url。

640.png

其中,limit代表返回酒店的最大数量(经测试,limit最大为50),offset为每次返回酒店数量的起点,cityId为城市的标志,在网页信息中可以找到,时间参数可以修改,sort为返回酒店信息的排序,sort=distance代表按距离搜索,q和keyword都是大学名称。

  返回的数据如下图所示:

640.png

包含酒店的名字、地理位置、评分、realPoiId(相当于酒店的身份证号,后面爬评论用的到)、酒店和大学的距离等信息。

下面我们开始爬排名前10高校附近的酒店信息(不要在乎大学排名,我乱找的,以学习为主):

640.jpg

部分代码如下图所示:
640.png

其中cityId和大学名字为控制变量,通过返回的距离信息将酒店位置控制在2000米以内,输出结果为:
640.jpg

  看看这10所大学2000米附近附近有多少家酒店:
640.png

我们可以发现,南京大学附近酒店最多,有453家;上海交通大学闵行校区附近酒店最少,有75家。

二、抓取每家酒店的点评信息

640.png

这个从这个url可以返回每家酒店的评论数量,poiId是酒店的“身份证号”。

1.png

这个url可以返回酒店的所有评论信息,其中limit为返回的评论数量,可以直接用上个url返回的评论数量,一次全部以json格式返回,非常方便,返回结果如下:
1.png

三、遇到的坑
1.刚开始爬评论是1次返回15个,后来发现可以Limit可以为评论的最大值,但是第一步返回的酒店信息中包含酒店评论数量是不准确的,要用第二步的方法;

  2.评论中乱七八糟的表情、符号也是大坑,去了好久也去不干净;

  3.最好用代理IP地址爬,否则评论太多,会被封。

3 结语

  本文基于Python网络爬虫,抓取了高校旁边的酒店数量及其评论数量,如果你想抓取其他地方的其他信息,也是可行的,可以纵向拓展。


全部代码:[mw_shl_code=python,true]import requests
import json
import re
import time
import emoji
import threading
from bs4 import BeautifulSoup
from urllib.parse import unquote#乱码转中文
from urllib.parse import quote #中文转乱码
header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
urlHttp='http://kuyukuyu.com/agents/get?uuid=1e660236-f391-40ef-929c-5f77dd1f5e1e'
def GetHotel(k):  #获得大学附近的酒店信息
    m = str(k).split(',')
    univesity=quote(m[1],encoding="utf-8")
    n=0
    flag=0  #以下循环的标志
    while flag==0:
        url='https://ihotel.meituan.com/hbsearch/HotelSearch'
        data={
            'utm_medium':'touch', 'version_name':'999.9','platformid':'1',
            'cateId':'20','newcate':'1','limit':'50','offset':'{0}'.format(50*int(n)),
            'cityId':'{0}'.format(m[0]),'ci':'1','startendday':'20200227~20200228',
            'startDay':'20200227','endDay':'20200228',
            'q':'{0}'.format(m[1]),'mypos':'39.735289%2C116.348179','attr_28':129,'sort':'distance',
            'userid':92855137,'uuid':'4498BB1F75C3C462E049855731E27FDEF4F7466C4099B649CE23FD0ECA63DF7B',
            'lat':'39.735289','lng':'116.348179','keyword':'{0}'.format(m[1]),'accommodationType':1
        }
        response=requests.get(url,headers=header,params=data)
        jsons=json.loads(response.text)['data']['searchresult']
        num = 0
        for i in jsons:
            name = i['name']  # 酒店名字
            addr = i['addr']  # 酒店地址
            lowestPrice = i['lowestPrice'] # 最低价
            scoreIntro = i['scoreIntro'] # 评分
            dis=i['dist'] #和大学之间的直线距离
            if dis<=2000: #爬2000米以内的酒店
                #print(name,addr,lowestPrice,scoreIntro,dis)
                num=num+1
                t=threading.Thread(target=get_comment,args=(i['realPoiId'],m[1],)) #get_comment为抓取评论的函数
                #print(i['realPoiId'])
                t.start()
            else:
                flag=1
        n=n+1
        all_num=n*50+num
    print(m[1]+"2000米附近有"+str(all_num)+'酒店')
def get_comment(realPoId,UniverCityName):#爬酒店评论数据,直到IsEnd=True,UniverCityName是大学的名字
    url='https://ihotel.meituan.com/api/v2/comments/biz/reviewCount?poiId={}'.format(realPoId)
    response=requests.get(url,headers=header)
    ReviewNum=json.loads(response.text)['Data']['Total']  #得到酒店最大评论数
    #print(ReviewNum,UniverCityName)
    url='https://ihotel.meituan.com/api/v2/comments/biz/reviewList'
    data={
        'referid':'{0}'.format(format(realPoId)),
        'limit':ReviewNum,#一次爬完所有评论
        'start':0,#本次爬的起始值
        'filterid':800,
        'querytype':1,
        'utm_medium':'touch',
        'version_name':999.9,
    }
    response=requests.get(url,headers=header,params=data)
    jsons=json.loads(response.text)
    CommentCounts=jsons['Data']['List']
    with open('{}.txt'.format(UniverCityName),'a')as f:
        for i in CommentCounts:
            text = str(i['Content']).replace(' ','').replace('\r','')#去掉表情
            Emoji = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF][\u2000-\u2fff]]')#去掉奇怪符号
            text = Emoji.sub('',text)
            text=emoji.demojize(text) #替换表情
            text = re.sub(':\S+?:', '', text)
            text = text.replace('#', '')
            print(text)
            f.write(text)

def main():
    infor = ['1,清华大学', '1,北京大学',
             '57,武汉大学', '50,浙江大学玉泉校区',
             '10,上海交通大学闵行校区', '10,复旦大学',
             '42,西安交通大学', '55,南京大学','20,中山大学','1,中国人民大学']  # 名字前的数字代表CityId
    for k in infor:
        t=threading.Thread(target=GetHotel,args=(k,))
        t.start()
if __name__=='__main__':
    main()[/mw_shl_code]

相关地址:
https://github.com/cassieeric/python_crawler/blob/master/Campus_hotel_comment/get_hotel_comment.py




最新经典文章,欢迎关注公众号

原文链接
https://mp.weixin.qq.com/s/wYb_Gck2DrlA2ocaF3i_fQ




本帖被以下淘专辑推荐:

已有(1)人评论

跳转到指定楼层
co_hen 发表于 2020-3-10 02:31:12
飞飞带我飞,飞呀飞
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条