心尊门 发表于 2019-8-20 08:00:54

爬虫去哪儿景点分析



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

因为是学习,所以请不要爬取正式环境去测试,因为容易被封,所以我们使用他们的测试环境测试,首先看一下域名: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"

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



如上图,所有的热门城市都在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'}).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

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

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



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

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'}).find_all('a')

# 得到a标签中的href

    page_url = page['href']

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

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

# 将完整的页数的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页信息

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



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

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

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'}).find_all('div',

{'class':'sight_item'})

for c in jingdian:

# 景点名

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

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

try:

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

except:

            jd_jb ='普通景区'

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

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

# 景点介绍

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

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

try:

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

except:

            jd_price =0

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

try:

            jd_xiaoliang = c.find_all('span',{'class':'hot_num'}).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'}).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'}).find_all('a')

# 得到a标签中的href

    page_url = page['href']

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

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

# 将完整的页数的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'}).find_all('div',

{'class':'sight_item'})

for c in jingdian:

# 景点名

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

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

try:

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

except:

            jd_jb ='普通景区'

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

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

# 景点介绍

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

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

try:

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

except:

            jd_price =0

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

try:

            jd_xiaoliang = c.find_all('span',{'class':'hot_num'}).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了。

页: [1]
查看完整版本: 爬虫去哪儿景点分析