易德轩网教学培训视频直播平台

使用论坛账号

 找回密码
登录
 立即注册

QQ登录

只需一步,快速开始

扫一扫,极速登录

搜索
查看: 994|回复: 0

爬虫去哪儿景点分析

[复制链接]
发表于 2019-8-20 08:00:54 | 显示全部楼层 |阅读模式
w1.jpg

爬取去哪儿网的旅游景点以及价格和介绍

因为是学习,所以请不要爬取正式环境去测试,因为容易被封,所以我们使用他们的测试环境测试,首先看一下域名:http://piao.qunar.com

我要爬取国内热门城市中的景点,因为爬取的数据我要保存到我的数据库中,所以我们先把数据库环境做好,直接安装mysql数据库,然后创建一个用户名并设置密码,设置密码后需要设置权限,并且设置数据库允许客户端访问,程序才可以写数据到数据库中。

设置允许远程访问并设置权限:

    mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;##如果不使用root用户可以替换掉自己的用户

重载授权表:

    FLUSH PRIVILEGES;

退出mysql数据库:

    exit

如果设置只允许程序所在的机器访问把“%”换成自己的IP即可。这里设置的权限比价大,只是测试使用。
创建数据库表

首先创建的是数据库,因为介绍中有汉字所以需要utf-8

    CREATE DATABASE `quna` CHARACTER SET utf8 COLLATE utf8_general_ci;

创建库后在创建表

    CREATE TABLE qu_na(

        id INT(20) AUTO_INCREMENT PRIMARY KEY COMMENT 'id',

        city_name VARCHAR(20) NOT NULL COMMENT '城市名',

        jd_name VARCHAR(30) NOT NULL COMMENT '景点名称',

        jd_jb VARCHAR(20) NOT NULL COMMENT '景点级别',

        jd_jieshao VARCHAR(50) NOT NULL COMMENT '景点介绍',

        jd_price VARCHAR(10) NOT NULL COMMENT '景点价格',

        jd_xiaoliang VARCHAR(10) NOT NULL COMMENT '景点销量');

已经了解到自己要爬取到内容,下面就根据自己爬取到内容进行分析:

首先,访问页面找到一些热点城市的代码,我们做一些标记:

    class="mp-sidebar-title"

就是全国热门城市,找到城市列表,分别取每个热门城市的[href]链接,然后对页面在具体分析:

w2.jpg

如上图,所有的热门城市都在class="mp-sidebar-list"中,我们需要爬取的过程中爬取ul中的li,因为li中包含了所有城市。

    #!/usr/bin/env python

    #-*-coding:utf-8-*-

    import requests

    from bs4 importBeautifulSoup

    import re

    # 解析出每个城市及其该城市对应的url

    def parse_city(url):

    #这里先定义一下url的状态,如果错误就不执行

        status = requests.get(url).status_code

    if status ==200:

            html = requests.get(url, headers=headers)

            html = html.text

            soup =BeautifulSoup(html,'lxml')#

            city = soup.find_all('ul',{'class':'mp-sidebar-list','mp-role':'hotCityList'})[0].find_all('li')

    for i in city:

    # 得到每个城市的名字和对应的url

                city_name = i.a.text

                city_url = i.a['href']

                city_url = url + city_url

    print("热门城市:",city_name,"热门城市路径:",city_url)

    else:

    return404

    if __name__ =='__main__':

        headers ={

    'User-Agent':'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)',}

        start_url ='http://piao.qunar.com/'

        parse_city(start_url)

查看一下执行结果:

    热门城市:北京热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=北京&region=北京&from=mpshouye_hotcity

    热门城市:上海热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=上海&region=上海&from=mpshouye_hotcity

    热门城市:成都热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=成都&region=成都&from=mpshouye_hotcity

    热门城市:三亚热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=三亚&region=三亚&from=mpshouye_hotcity

    热门城市:广州热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=广州&region=广州&from=mpshouye_hotcity

    热门城市:重庆热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=重庆&region=重庆&from=mpshouye_hotcity

    热门城市:深圳热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=深圳&region=深圳&from=mpshouye_hotcity

    热门城市:西安热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=西安&region=西安&from=mpshouye_hotcity

    热门城市:杭州热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=杭州&region=杭州&from=mpshouye_hotcity

    热门城市:厦门热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=厦门&region=厦门&from=mpshouye_hotcity

    热门城市:武汉热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=武汉&region=武汉&from=mpshouye_hotcity

    热门城市:大连热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=大连&region=大连&from=mpshouye_hotcity

    热门城市:苏州热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=苏州&region=苏州&from=mpshouye_hotcity

    热门城市:青岛热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=青岛&region=青岛&from=mpshouye_hotcity

    热门城市:天津热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=天津&region=天津&from=mpshouye_hotcity

    热门城市:南京热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=南京&region=南京&from=mpshouye_hotcity

    热门城市:香港热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=香港&region=香港&from=mpshouye_hotcity

    热门城市:桂林热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=桂林&region=桂林&from=mpshouye_hotcity

    热门城市:郑州热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=郑州&region=郑州&from=mpshouye_hotcity

    热门城市:昆明热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=昆明&region=昆明&from=mpshouye_hotcity

所有的热门城市已经爬取完成,下面对于每一个城市爬取城市,景点,景点级别,景点介绍,景点价格,景点销售。分别提取出来,然后在写到数据库中。

已经找到所有的热门城市,下面针对所有的热门城市做一下分析如图:

w3.jpg

先找出所有的热门城市,在把每个热门城市的景点都找出来,然后对于每个景点在分析,需要上面的函数调用下面的函数,在上面函数打印热门城市下调用一下这个函数:

    def city_page(city_name, city_url):

        html = requests.get(city_url, headers=headers)

        html = html.text

        soup =BeautifulSoup(html,'lxml')

        page = soup.find_all('div',{'class':'pager'})[0].find_all('a')

    # 得到a标签中的href

        page_url = page[0]['href']

    # 得到下一页的url,这个url由我们来指定,只需把页数前面的字符串匹配出来即可

        page_select_url = re.findall('(.*page=)', page_url)[0]

    # 将完整的页数的url拼接起来

        page_select_url ='http://piao.qunar.com'+ page_select_url

    # 这里选-2是有深意的,因为在选择每一页的地方倒一是下一页,而倒二则是尾页数

        page_num =int(page[-2].text)

    print('有%s页的数据'% page_num)

    for i in range(1, page_num +1):

    # 遍历得到某个城市中所有页数

    print('第%d页信息'% i)

            parse_page_url = page_select_url + str(i)

    print('网页地址:', parse_page_url)

之后后的结果:

    热门城市:北京热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=北京&region=北京&from=mpshouye_hotcity

    有257页的数据

    第1页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=1

    第2页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=2

    第3页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=3

    第4页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=4

    第5页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=5

    第6页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=6

    第7页信息

    网页地址: http://piao.qunar.com/ticket/list_%E5%8C%97%E4%BA%AC_%E5%8C%97%E4%BA%AC.html?from=mpshouye_hotcity&page=7

    第8页信息

针对每一个热门城市中的景点进行分析代码如下图:

w4.jpg

我们需要找到的城市名称,景点名称,景点级别,景点介绍,景点价格,景点销量。需要对于每个热门城市的页面进行分析:

    #解析每个城市每一页的信息

    def parse_page(city_name, parse_page_url):

        html = requests.get(parse_page_url, headers=headers)

        html = html.text

        soup =BeautifulSoup(html,'lxml')

        jingdian = soup.find_all('div',{'class':'result_list','id':'search-list'})[0].find_all('div',

    {'class':'sight_item'})

    for c in jingdian:

    # 景点名

            jd_name = c.find_all('a',{'data-click-type':'l_title','class':'name'})[0].text

    # 景点级别,有的景区无级别,所以要设置一个异常

    try:

                jd_jb = c.find_all('span',{'class':'level'})[0].text

    except:

                jd_jb ='普通景区'

    # text得到的是  地址:北京市东城区景山前街4号  这种格式,所以以空格拆分,取后面那个

            jd_address = c.find_all('p',{'class':{'address','color999'}})[0].text.split()[-1]

    # 景点介绍

            jd_jieshao = c.find_all('div',{'class':{'intro','color999'}})[0].text

    # 景点价格,有的是免费,并无价格这一参数,所以设置一个异常

    try:

                jd_price = c.find_all('span',{'class':'sight_item_price'})[0].find_all('em')[0].text

    except:

                jd_price =0

    # 有的是免费,并销量这一参数,所以设置一个异常

    try:

                jd_xiaoliang = c.find_all('span',{'class':'hot_num'})[0].text

    # 景点销量

                jd_xiaoliang =int(jd_xiaoliang)

    except:

                jd_xiaoliang =0

    print('{0}  {1}  {2}  {3}  {4}'.format(jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang))

打印结果:

    热门城市:北京热门城市路径: http://piao.qunar.com//ticket/list.htm?keyword=北京&region=北京&from=mpshouye_hotcity

    故宫5A景区一起来逛逛紫禁城”庙会“吧2012810

    八达岭长城5A景区不到长城非好汉1402799

    颐和园5A景区保存完整的一座皇家行宫御苑361206

    天安门广场普通景区我爱北京天安门,天安门上太阳升203573

    圆明园4A景区追忆昔日万园之园254052

    鸟巢5A景区北京的地标,中华民族崛起的象征49832

    水立方普通景区中国的荣耀,阳光下的晶莹水滴14526

    什刹海4A景区老北京的温柔乡,北京签到地51692

    天坛公园5A景区探寻古代皇帝祭天仪式的奥秘2.3222

    慕田峪长城5A景区电影《非诚勿扰》取景地20598

至此,爬取已经完成,下面就是把爬取的页面写到数据中,下面那完整代码贴出来。

    #!/usr/bin/env python

    #-*-coding:utf-8-*-

    import requests

    from bs4 importBeautifulSoup

    import re

    import pymysql

    # 解析出每个城市及其该城市对应的url

    def parse_city(url):

        status = requests.get(url).status_code

    if status ==200:

            html = requests.get(url, headers=headers)

            html = html.text

            soup =BeautifulSoup(html,'lxml')

            city = soup.find_all('ul',{'class':'mp-sidebar-list','mp-role':'hotCityList'})[0].find_all('li')

    for i in city:

    # 得到每个城市的名字和对应的url

                city_name = i.a.text

                city_url = i.a['href']

                city_url = url + city_url

    print("热门城市:",city_name,"热门城市路径:",city_url)

                city_page(city_name, city_url)

    else:

    return404

    # 解析出每个城市的url的下一页

    def city_page(city_name, city_url):

        html = requests.get(city_url, headers=headers)

        html = html.text

        soup =BeautifulSoup(html,'lxml')

        page = soup.find_all('div',{'class':'pager'})[0].find_all('a')

    # 得到a标签中的href

        page_url = page[0]['href']

    # 得到下一页的url,这个url由我们来指定,只需把页数前面的字符串匹配出来即可

        page_select_url = re.findall('(.*page=)', page_url)[0]

    # 将完整的页数的url拼接起来

        page_select_url ='http://piao.qunar.com'+ page_select_url

    # 这里选-2是有深意的,因为在选择每一页的地方倒一是下一页,而倒二则是尾页数

        page_num =int(page[-2].text)

    #print('有%s页的数据' % page_num)

    for i in range(1, page_num +1):

    # 遍历得到某个城市中所有页数

    #print('第%d页信息' % i)

            parse_page_url = page_select_url + str(i)

    #print('网页地址:', parse_page_url)

    # 将每一页的url都传递到parse_page中进行解析

            parse_page(city_name, parse_page_url)

    # 解析每个城市每一页的信息

    def parse_page(city_name, parse_page_url):

        html = requests.get(parse_page_url, headers=headers)

        html = html.text

        soup =BeautifulSoup(html,'lxml')

        jingdian = soup.find_all('div',{'class':'result_list','id':'search-list'})[0].find_all('div',

    {'class':'sight_item'})

    for c in jingdian:

    # 景点名

            jd_name = c.find_all('a',{'data-click-type':'l_title','class':'name'})[0].text

    # 景点级别,有的景区无级别,所以要设置一个异常

    try:

                jd_jb = c.find_all('span',{'class':'level'})[0].text

    except:

                jd_jb ='普通景区'

    # text得到的是  地址:北京市东城区景山前街4号  这种格式,所以以空格拆分,取后面那个

            jd_address = c.find_all('p',{'class':{'address','color999'}})[0].text.split()[-1]

    # 景点介绍

            jd_jieshao = c.find_all('div',{'class':{'intro','color999'}})[0].text

    # 景点价格,有的是免费,并无价格这一参数,所以设置一个异常

    try:

                jd_price = c.find_all('span',{'class':'sight_item_price'})[0].find_all('em')[0].text

    except:

                jd_price =0

    # 有的是免费,并销量这一参数,所以设置一个异常

    try:

                jd_xiaoliang = c.find_all('span',{'class':'hot_num'})[0].text

    # 景点销量

                jd_xiaoliang =int(jd_xiaoliang)

    except:

                jd_xiaoliang =0

    #print('{0}  {1}  {2}  {3}  {4}'.format(jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang))

            mysql(city_name, jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang)

    # 定义一个类,将连接MySQL的操作写入其中

    class down_mysql:

    def __init__(self, city_name, jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang):

    self.city_name = city_name

    self.jd_name = jd_name

    self.jd_jb = jd_jb

    self.jd_jieshao = jd_jieshao

    self.jd_price = jd_price

    self.jd_xiaoliang = jd_xiaoliang

    self.connect = pymysql.connect(

                host='10.211.55.14',

                db='quna',

                port=3306,

                user='root',

                passwd='123456',

                charset='utf8',

                use_unicode=False

    )

    self.cursor =self.connect.cursor()

    # 保存数据到MySQL中

    def save_mysql(self):

            sql ="insert into qu_na(city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang) VALUES (%s,%s,%s,%s,%s,%s)"

    try:

    self.cursor.execute(sql,(

    self.city_name,self.jd_name,self.jd_jb,self.jd_jieshao,self.jd_price,self.jd_xiaoliang))

    self.connect.commit()

    print('数据插入成功')

    except:

    print('数据插入错误')

    def mysql(ciry_name, jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang):

    # 新建类,将数据保存在MySQL中

        down = down_mysql(ciry_name, jd_name, jd_jb, jd_jieshao, jd_price, jd_xiaoliang)

        down.save_mysql()

    if __name__ =='__main__':

        headers ={

    'User-Agent':'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)',}

        start_url ='http://piao.qunar.com/'

        parse_city(start_url)

这里需要注意的是,这里爬取的是http,https需要使用ssl模块,并且增加一句

    ssl._create_default_https_context = ssl._create_unverified_context

放在定义的url前面。

如果你是新同学,长按下面二维码 - 识别图中二维码 - 关注,就可以每天一起学Python了。

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

本版积分规则

回手机版|论坛帮助|易德轩网 ( 鲁ICP备20005112号-2 )|网站地图

GMT+8, 2024-11-23 03:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表