旅游网-去哪儿网景点评论爬取

前言

 最近由于学校的项目需要用到旅游相关的数据集,而与这方面相关的又必要少,于是就想到通过python爬虫自己去爬取。
 由于我也是初次接触爬虫,很多知识点还不会,方式可能有点粗暴,但终归还是爬取了,可能就是慢了点,和自己要时刻手操下(づ ̄ 3 ̄)づ
长话短说,现在开始吧<( ̄︶ ̄)↗[GO!]

正文

第一步
首先要获取城市的id,这个需要从(http://travel.qunar.com/place/)获取
在这里插入图片描述
这个页面可以就直接右键查看代码,然而根据相应信息进行提取,这里我保存为city.csv文件,代码如下:

from bs4 import BeautifulSoup
import pandas as pd
import requests

def get_static_url_content(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    req=requests.get(url,headers=headers)
    content=req.text
    bsObj=BeautifulSoup(content,'lxml')
    return bsObj

def get_city_id():
    url = 'http://travel.qunar.com/place/'
    bsObj=get_static_url_content(url)
    cat_url = []
    cat_name = []
    bs=bsObj.find_all('div',attrs={'class':'sub_list'})

    for i in range(0,len(bs)):
        xxx = bs[i].find_all('a')
        for j in range(0,len(xxx)):
            cat_name.append(xxx[j].text)
            cat_url.append(xxx[j].attrs['href'])
    return cat_name,cat_url

city_name_list,city_url_list=get_city_id()
city=pd.DataFrame({'city_name':city_name_list,'city_code':city_url_list})
city.to_csv('city.csv',encoding='utf_8_sig')

运行完,你将得到csv文件,打开得到
在这里插入图片描述
到这里已经获取某个城市id,将为第二步做准备

第二步
爬取具体某个城市景点id,这里以杭州举例http://travel.qunar.com/p-cs300195-hangzhou
在这里插入图片描述
爬取http://travel.qunar.com/p-cs300195-hangzhou-jingdian中的景点id,代码如下:

from bs4 import BeautifulSoup
import pandas as pd
import requests

def get_static_url_content(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    req=requests.get(url,headers=headers)
    content=req.text
    bsObj=BeautifulSoup(content,'lxml')
    return bsObj

def get_jd_url(url):
    #该城市最大景点数
    maxnum = get_static_url_content(url+'-jingdian').find('p',{'class':'nav_result'}).find('span').text
    #提取数字
    maxnum=int(''.join([x for x in maxnum if x.isdigit()]))

    url=url+'-jingdian-1-'
    cat_url = []
    cat_name = []

    # 这里取top100景点 每页10条 page从1开始
    page=11
    # 判断是否超过范围
    if (page-1)*10>maxnum :
        page=int(((maxnum+10)/10)+1)

    for i in range(1,page):
        url1=url+str(i)
        bsObj=get_static_url_content(url1)
        bs=bsObj.find_all('a',attrs={'data-beacon':'poi','target':'_blank'})
        for j in range(0, len(bs)):
            if(bs[j].text!=''):
                cat_name.append(bs[j].text)
                cat_url.append(bs[j].attrs['href'])
    print(cat_name,cat_url)
    print(len(cat_name))
    print(len(cat_url))
    return cat_name, cat_url

#杭州举例
url='http://travel.qunar.com/p-cs300195-hangzhou'
city_name_list,city_url_list=get_jd_url(url)
city=pd.DataFrame({'city_name':city_name_list,'city_code':city_url_list})
city.to_csv('hangzhou-jd-top100.csv',encoding='utf_8_sig')

结果是
在这里插入图片描述

第三步
这里将以西湖http://travel.qunar.com/p-oi708952-xihu为例,爬取评论数据
注意,这里的评论都是动态加载的(注意到不管点第几页浏览器的地址栏都是不变的),我们随意点一页看一下,比如第二页:
在这里插入图片描述
所以通过chrome F12检测数据传输,发现每次点击下一页,都会发生回复json请求,在Network-XHR出现新的请求,双击打开可以发现我们要的数据
例如http://travel.qunar.com/place/api/html/comments/poi/708952?poiList=true&sortField=1&rank=0&pageSize=10&page=2
在这里插入图片描述
我们能很容易从这里找到规律,poi后的数字就是景点id,pageSize就是一次请求回复多少评论,通过查看文件,可以知道最大设为50,page为页数,当超过页数时,则没有信息,代码如下:

from bs4 import BeautifulSoup
import pandas as pd
import json
import requests
import time

def get_static_url_content(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    req = requests.get(url, headers=headers)
    content = req.text
    bsObj = BeautifulSoup(content, 'lxml')
    return bsObj

def get_jd_comment(url):
    # 该景点最大评论数
    maxnum = get_static_url_content(url).find('span', {'class': 'e_nav_comet_num'}).text
    maxnum = int(maxnum)

    poi = ''.join([x for x in url if x.isdigit()])

    cat_user_id = []
    cat_user_name= []
    cat_jd_poi = []
    cat_score = []
    cat_user_comment = []
    cat_comment_time = []

    url = 'http://travel.qunar.com/place/api/html/comments/poi/' + poi + '?poiList=true&sortField=1&rank=0&pageSize=50&page='
    #这里页数暂时设为101,取的pageSize=50,即爬取100*50条评论
    page = 101
    if (page - 1) * 50 > maxnum:
        page = int(((maxnum + 50) / 50)+1)
    for i in range(1, page):
        url1 = url + str(i)
        json_str = requests.get(url1, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}).text
        json_data=json.loads(json_str)['data']
        #print(json_data)
        bsObj = BeautifulSoup(json_data, 'lxml')
        bs=bsObj.find_all('li',{'class':'e_comment_item clrfix'})

        for j in range(0,len(bs)):
            try:
                user=bs[j].find('div', {'class': 'e_comment_usr_name'}).find('a')
                cat_user_id.append(''.join([x for x in user.attrs['href'] if x.isdigit()]))

                cat_user_name.append(user.text)

                cat_jd_poi.append(poi)

                score=''.join([x for x in str(bs[j].find('span',{'class':'total_star'}).find('span')) if x.isdigit()])
                cat_score.append(score)

                a=bs[j].find('div',{'class':'e_comment_content'}).find_all('p')
                cat_user_comment.append(''.join(x.text for x in a))

                cat_comment_time.append(bs[j].find('div',{'class':'e_comment_add_info'}).find('li').text)

            except:
                print('i=',i,'j=',j,'有问题')
        print('已完成poi=',poi,' ',i,'/',page-1)
        time.sleep(0.2)

    return cat_user_id,cat_user_name,cat_jd_poi,cat_score,cat_comment_time,cat_user_comment

# 西湖举例
url = 'http://travel.qunar.com/p-oi708952-xihu'
cat_user_id,cat_user_name,cat_jd_poi,cat_score,cat_comment_time,cat_user_comment=get_jd_comment(url)
city=pd.DataFrame({'user_id':cat_user_id,'user_name':cat_user_name,'jd_poi':cat_jd_poi,'score':cat_score,'time':cat_comment_time,'comment':cat_user_comment})
city.to_csv('xihu-jd-comment.csv',encoding='utf_8_sig')

爬取结果为:
在这里插入图片描述
 第三步爬取时,有时会因为ip大量访问而被暂时禁止,需要登陆该正在被爬取景点地址,输入验证码才解禁,所以你可以使用IP代理爬取

结束

 到此就结束了,最后关于整合遍历爬全国景点就暂时没整理了,以后有机会再发吧

猜你喜欢

转载自blog.csdn.net/sdozouhao2007/article/details/84404982