前言

最近购买了《Python3 爬虫、数据清洗与可视化实战》,刚好适逢暑假,就尝试从携程页面对广州的周边游产品进行爬虫数据捕捉。

因为才学Python不够一个星期,python的命名规范还是不太了解,只能套用之前iOS开发的命名规范,有不足之处请多多指点

一、前期

1.主要用到的库

from bs4 import BeautifulSoup

import time

import re #正则表达式

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.common.action_chains import ActionChains #浏览器操作

import xlrd

import xlwt

from xlutils.copy import copy

import os

BeautifulSoup:用于对标签等数据进行定位和抓取

selenium:用于启动浏览器和对页面进行自动操作

time:暂停等待操作

xlrd、xlwt、xlutils:对数据结果进行Excel读写保存操作

2.核心思路

1,跳进出发点的周边游页面(广州)

2,在首页捕捉推荐的热门目的地和热点景点,进行保存

3,针对目的地地点进行遍历搜索所展示的旅游产品

4,产品数据参数抓取

5,数据保存

6,退出浏览器

二、代码

1.启动浏览器

def setupDriverSetting():

global driver

# url = 'http://m.ctrip.com/restapi/soa2/10290/createclientid?systemcode=09&createtype=3&conte'#获取cookieID

# 手机端

# url = 'https://m.ctrip.com/webapp/vacations/tour/list?tab=64&kwd=%E7%8F%A0%E6%B5%B7&salecity=32&searchtype=tour&sctiy=32'

# 电脑端

url = 'https://weekend.ctrip.com/around/'

# 设置用chrome启动

driver = webdriver.Chrome()

# #设置fireFox请求头参数

# profile = webdriver.FirefoxProfile()

# user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0"

# profile.set_preference("general.useragent.override",user_agent)

#

# driver = webdriver.Firefox(profile)

driver.get(url)

用webdriver启动Chrome或者fireFox,并跳进首页URL

2.选择出发点城市

def select_StartPlace(startPlace):

#点击出发点view

driver.find_element_by_xpath("//*[@id='CitySelect']").click()

#选择出发点

cityList = driver.find_elements_by_xpath("//*[@id='CitySelect']/dd/ul")

for link in cityList:

links = link.find_elements(By.TAG_NAME,"a")

for eachCity in links:

cityStr = eachCity.text

if cityStr == startPlace:

print("找到目标城市:"+eachCity.get_attribute('href'))

driver.get(eachCity.get_attribute('href'))

time.sleep(2)

try:

WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='SearchText']")))

except:

print('出发地页面加载不成功')

break

主要是用find_element_by_xpath寻找目标城市进行选择筛选,然后跳到城市专页

3.搜索目的地

def finAllDestinationPage():

#查找总数组

destType = driver.find_element_by_id("J_sub_circum")#id 决定产品范围(周边游,境外游)

print(destType.text)

destType1 = destType.find_element_by_class_name("side_jmp_dest")

destTypeItem = destType1.get_attribute('innerHTML')

item = BeautifulSoup(destTypeItem,'lxml')

destTypeList = item.find_all('li')

allDestinationListDic = {}

for each in destTypeList:

typeName = each.h4.string

typeList = each.find_all('a')

list = []

for i in typeList:

list.append(i.string)

allDestinationListDic[typeName] = list

return allDestinationListDic

搜索所有可推荐目的地和景点,并用字典保存

4.旅游产品列表页

def jump_destinationPage(startPlace,destination):

#定位搜索栏

try:

WebDriverWait(driver,5).until(EC.presence_of_element_located((By.XPATH,"//*[@id='SearchText']")))

except:

print('查找不到搜索栏')

finally:

print('本地页面加载完毕')

driver.find_element_by_xpath("//input[@id='SearchText']").send_keys(destination)

print("输入目的地:"+destination)

driver.find_element_by_xpath("//*[@id='SearchBtn']").click()

print("点击搜索按钮结束")

time.sleep(2)

try:

WebDriverWait(driver,5).until(EC.presence_of_element_located((By.XPATH,"//*[@id='js-dpSearcher']")))

except:

print('产品列表页加载不成功')

finally:

print('产品列表页加载完毕')

#再选一次出发地,以防出错

reSelect_StartPlace(startPlace)

#搜索页数

pageHtml = driver.find_element_by_xpath("//*[@id='_sort']/div/span")

print(pageHtml.text)

pageNumStr = pageHtml.text

pageNumStr = pageNumStr[:-1]

print("获取的num:" + pageNumStr)

#正则表达式 查找页数

pageNumS = re.findall(r'\d+',pageNumStr)

pageNum = int(pageNumS[1])

print(pageNum)

tourProductList = []

for i in range(0,pageNum):

itemList = showCurrentPageAllData()

#收集数据

for j in range(0,len(itemList)):

eachItem = collectCurrentPageEachData(j)

tourProductList.append(eachItem)

#点击下一页

driver.find_element_by_xpath("//input[@id='ipt_page_txt']").clear()

driver.find_element_by_xpath("//input[@id='ipt_page_txt']").send_keys(str(i+2))

driver.find_element_by_xpath("//*[@id='ipt_page_btn']").click()

print("点击下一页结束->"+str(i+2)+"页")

time.sleep(2)

return driver

跳进产品页,并根据标签,抓取总页数,在遍历所有旅游产品后,再跳到下一页进行循环遍历

5.产品数据抓取

def collectCurrentPageEachData(itemNum):

itemList = driver.find_elements_by_class_name("product_box")

str = itemList[itemNum].get_attribute('innerHTML')#转换成字符串

# item = BeautifulSoup(str,"html.parser")#获取item的soup对象

item = BeautifulSoup(str, "lxml") # 获取item的soup对象

# print("+++++++"+item.prettify())

# 解析

#产品名称

titleNameHtml = item.find('h2',class_= 'product_title')

print("-------"+titleNameHtml.get_text())

productName = titleNameHtml.get_text()

#产品链接

productLink = titleNameHtml.a['href']

productLink = productLink[2:]

productLink = "https://"+productLink

print("link:" + productLink)

#产品类型

productType = item.find('em')

print("type:"+productType.get_text())

productTypeStr = productType.get_text()

#产品价格

priceHtml = item.find('span',class_='sr_price')

priceStr = priceHtml.strong.get_text()

#判断是否为数字

if priceStr.isdigit() == True :

priceStr = "%.2f"%float(priceStr)

print("price:"+priceStr)

#产品供应商

productRetail = item.find('p',class_='product_retail')

productRetailStr = productRetail['title']

if "供应商" in productRetailStr:

productRetailStr = productRetailStr[4:]

print("retail:" + productRetailStr)

#产品评分

try :

gradeHtml = item.find('p', class_='grade')

gradeStr = gradeHtml.strong.get_text()

print("grade:" + gradeStr)

except:

print('查找不到评分')

gradeStr = ''

# 产品人数

try:

commentHtml = item.find('div', class_='comment')

commentStr = commentHtml.em.get_text()

commentNumS = re.findall(r'\d+', commentStr)

commentNum = int(commentNumS[0])

print("comment:",commentNum)

except:

print('查找不到出游人数')

commentNum = ''

return {

'名称':productName,

'链接':productLink,

'类型':productTypeStr,

'价格':priceStr,

'供应商':productRetailStr,

'评分':gradeStr,

'人数':commentNum,

}

在产品页面上获取所有可见信息,并返回

6.数据保存

class ExcelFileManager:

def creatExcelFile(fileName,sheetName,headRowList):

# 获取项目所在目录

filePath = os.getcwd() + '/' + fileName + '.xls'

#如果不存在就新增

try:

oldFile = xlrd.open_workbook(filePath)

file = copy(oldFile)

except:

file = xlwt.Workbook()

print("新建文件")

#如果不存在就新增

try:

sheet1 = file.add_sheet(sheetName,cell_overwrite_ok=True)

except:

sheet1 = file.get_sheet(sheetName)

#设置style样式

head_style = xlwt.easyxf('font: name Times New Roman, color-index red, bold on',num_format_str='#,##0.00')

row0 = headRowList

for i in range(0,len(row0)):

sheet1.write(0,i,row0[i],head_style)

print(filePath)

file.save(filePath)

def addDataToExcelFile(fileName,sheetName,dataList):

filePath = os.getcwd()+'/'+fileName+'.xls'

file = xlrd.open_workbook(filePath)

#已存在的行数

newRows = file.sheet_by_name(sheetName).nrows

new_File = copy(file)

sheet = new_File.get_sheet(sheetName)

try:

for i in range(0,len(dataList)):

for j in range(0,len(dataList[i])):

sheet.write(i+newRows,j,dataList[i][j])

except Exception as e:

print(e)

new_File.save(filePath)

Excel文件创建与保存数据,不得不说,python对Excel支持不是很友好,xlrd和xlwt仅支持读和写,不支持增加sheet或者在原有Excel文件上添加数据等操作,需要用到第三方库

三、抓取结果:

1530848043475.jpg

python 携程_python 携程爬虫开发笔记相关推荐

  1. python3携程_python携程

    介绍 协程(coroutine),又称为微线程,纤程.协程的作用:在执行A函数的时候,可以随时中断,去执行B函数,然后中断继续执行A函数(可以自动切换),单着一过程并不是函数调用(没有调用语句),过程 ...

  2. python asyncio教程_Python 协程模块 asyncio 使用指南

    Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...

  3. python gevent缺点_python 协程 greenlet gevent

    一.并发的本质 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长时间片到了 二.协程 ...

  4. python协成_Python协程(上)

    几个概念: event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上.当满足事件发生的时候,调用相应的协程函数. coroutine 协程:协程对象,指一个使用asy ...

  5. python使用协程_Python 协程使用心得

    基本概念 协程:又称微线程,纤程.英文名Coroutine.协程是一种子程序,它在执行过程中可以中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意:如程序内不需要中断,则不要定义成协程 ...

  6. python从网址爬图片协程_python协程gevent案例 爬取斗鱼图片过程解析

    分析 分析网站寻找需要的网址 用谷歌浏览器摁F12打开开发者工具,然后打开斗鱼颜值分类的页面,如图: 在里面的请求中,最后发现它是以ajax加载的数据,数据格式为json,如图: 圈住的部分是我们需要 ...

  7. python从网址爬图片协程_python协程gevent案例:爬取斗鱼美女图片

    分析 分析网站寻找需要的网址 用谷歌浏览器摁F12打开开发者工具,然后打开斗鱼颜值分类的页面,如图: 在里面的请求中,最后发现它是以ajax加载的数据,数据格式为json,如图: 圈住的部分是我们需要 ...

  8. python 协程_Python 协程与 Go 协程的区别(一)

    ? "Python猫" ,一个值得加星标的公众号 花下猫语:年关将近,不知各位过得怎样?我最近有些忙,收获也挺多,以后有机会分享下.吃饭时间,追了两部剧<了不起的麦瑟尔夫人& ...

  9. python协成_Python协程技术的演进

    引言 1.1. 存储器山 存储器山是 Randal Bryant 在<深入理解计算机系统>一书中提出的概念. 基于成本.效率的考量,计算机存储器被设计成多级金字塔结构,塔顶是速度最快.成本 ...

最新文章

  1. 深度学习(DL)与卷积神经网络(CNN)学习随笔-05-基于Python的LeNet之CNN
  2. as3通信AMF3协议的框架
  3. LSP(分层服务提供者)
  4. EFCore 5 新特性 Savepoints
  5. 面象对象设计6大原则之六:迪米特原则
  6. android开发蓝牙自动连接电脑上,Android蓝牙开发之自动连接设备
  7. drools 7.x 模板的简单使用
  8. 论文翻译:U-Net: Convolutional Networks for Biomedical Image Segmentation
  9. python获取交易软件数据_几行Python代码,轻松获取美股阿里巴巴的交易数据
  10. 服务器设置系统盘分页,服务器设置系统盘分页
  11. Windows核心编程_Edit控件无法输入问题
  12. python实现isprime_isPrime函数(列表+%运算符)
  13. 最新炫酷恶趣图制作神器小程序源码+支持流量主/功能强大
  14. IOS 代码修改故事版中的自动布局参数
  15. php mail 163邮箱,使用PHPMail发送邮箱(163邮箱为例)
  16. VR是TAA的终结者吗?
  17. 下载频道2013年超人气精华资源汇总---全都是免积分下载
  18. 哈工大人工智能暑期课实践项目——手写体识别四则运算(项目计划)
  19. 买股票也要会买跌,股票不是只有涨的时候才能买的
  20. 3D种类游戏系统开发

热门文章

  1. window服务器上搭建git服务,window server git!!!
  2. DRBD+keepalived+LAMP+discuz
  3. Hadoop问题:The auxService:mapreduce_shuffle does not exist
  4. 监控开发之用munin来自定义插件监控redis和mongodb
  5. iOS-项目常见文件
  6. speedtest-cli命令行下测试服务器外网速度
  7. 长的帅不是你的错,长的没特点就不应该了
  8. 10 个利用Eclipse调试Java的常见技巧
  9. 如何在数字化转型战略中真正获得价值?浅谈数字化转型的四个层级
  10. 程序员:要想成为一个伟大的程序员