Python

您所在的位置:网站首页 携程数据分析 Python

Python

2023-09-17 02:35| 来源: 网络整理| 查看: 265

携程在手 说走就走。今天来记录一下爬取携程旅行的教程。 首先告诉大家,爬携程还是相对简单的,当然也有难得方法,这里就以实现为最终目标讲解最简单得方法。在这里插入图片描述 我要采集得是携程门票一栏得景点信息。还是照惯例用chrome抓包。首先需要获取每个景点详情页的url,我这边找到了直接贴图。 在这里插入图片描述 原来以为拿到这个页面问题就解决了,可实践发现事情并没有我想的那么简单,这是一个post请求。我把参数都带上进行访问,压根拿不到数据。返回的json文件是这样的。 在这里插入图片描述 研究了一下,发现参数里有一个变动的加密参数‘traceid’,很明显每次请求都会生成一个一次性的加密参数,一次之后就过期无法复用,如果要走这个方法只能去做js逆向解密破解它,然而我内心是拒绝的,这不符合我的人物设定。 也给看到文章的朋友讲讲,如果你不是专注只做爬虫的话,其实没必要去研究js解密,因为首先你得会js。爬虫这个方向说实话入门的下限很低,但是上限非常高。如果你一心只搞爬虫,那可以花大把时间去研究,像我这种只拿爬虫作为工具的就不想花太多时间在这上面了。所以这里我改用selenium去获取数据,简单实用太香了。 在这里插入图片描述

selenium功能还是挺强大的,使用这个方法就可以拿到class值为’right-content-list’标签下的所有内容。然后就是正则匹配出每个景点详情页的url以及标题。拿到详情页的标题之后就可以requests请求详情页数据了。详情页的数据可以直接拿到比较简单。 然后在这里解释一下为什么要用while True死循环,因为携程在换页的时候它的url是不会变化的,所以这里只能用selenium的自动点击功能,让它在采完第一页数据之后自动跳转下一页进行采集,设置好你要爬取的页码,也就是我代码里的self.page的值,达到爬取的页数就跳出循环即可。 到了爬取详情页这一步,就看你想采什么样的数据去写规则了。在这里我只提一点,不难但是麻烦,大家在往下看之前也可以先思考一下。看下图。 在这里插入图片描述 图中的内容,有景点介绍 开放时间 优待政策几栏,但不是每个景点都是这几个,有的是只有一个,有的还有一个服务设备栏,而且看它的前端代码,属性标签啥的都是一模一样的,遇到这种情况如果是你会怎么去获取,才能保证不会少拿而且又能正确对应上数据? 思考令人进步。。。 下面给出我的答案! 在这里插入图片描述 我这里是把这个栏目的标题以及内容分别使用xpath提取形成两个列表,因为不管到底有几个内容,它的标题跟内容都肯定是一一对应上的,而列表是有序的。列表出来之后就是使用dict(zip(desc_title_list, desc_list)),先转json再转字典,标题就是key值,内容就是value值。如果要单独展示就遍历字典就可以了。这一步我代码里没写,大家自己去写吧。 要注意的点大致就这些,下面贴我的完整代码!!!

import pandas import re import time import requests import urllib3 from lxml import etree from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class Jy_jd(object): def __init__(self): options = Options() options.add_argument('--headless') self.chrome = Chrome(options=options) self.chrome.get( 'https://huodong.ctrip.com/things-to-do/list?pagetype=city&citytype=dt&keyword=%E6%8F%AD%E9%98%B3&pshowcode=Ticket2') time.sleep(3) self.page = 1 self.headers = { 'cookie': 'Session=SmartLinkCode=U155952&SmartLinkKeyWord=&SmartLinkQuary=&SmartLinkHost=&SmartLinkLanguage=zh; _RSG=KqK3qETfa143fOqQl4rFXB; _RDG=282f24100640c82731283334fcc3364464; _RGUID=4064a5d3-b40d-4d14-b84f-d44bdad18a43; Union=OUID=index&AllianceID=4897&SID=155952&SourceID=&createtime=1600831032&Expires=1601435831593; MKT_OrderClick=ASID=4897155952&AID=4897&CSID=155952&OUID=index&CT=1600831031597&CURL=https%3A%2F%2Fwww.ctrip.com%2F%3Fsid%3D155952%26allianceid%3D4897%26ouid%3Dindex&VAL={"pc_vid":"1600831028743.427gzc"}; MKT_CKID=1600831031634.5olt5.f6pj; MKT_CKID_LMT=1600831031635; _ga=GA1.2.248639397.1600831032; _gid=GA1.2.1954297618.1600831032; MKT_Pagesource=PC; GUID=09031031210931119554; nfes_isSupportWebP=1; appFloatCnt=1; nfes_isSupportWebP=1; ASP.NET_SessionSvc=MTAuNjAuMzUuMTQ2fDkwOTB8amlucWlhb3xkZWZhdWx0fDE1ODkwMDMyMjQ5NDI; U_TICKET_SELECTED_DISTRICT_CITY=%7B%22value%22%3A%7B%22districtid%22%3A%22835%22%2C%22districtname%22%3A%22%E6%8F%AD%E9%98%B3%22%2C%22isOversea%22%3Anull%7D%2C%22createTime%22%3A1600847243848%2C%22updateDate%22%3A1600847243848%7D; _RF1=113.118.204.141; _gat=1; _pd=%7B%22r%22%3A1%2C%22d%22%3A614%2C%22_d%22%3A613%2C%22p%22%3A634%2C%22_p%22%3A20%2C%22o%22%3A655%2C%22_o%22%3A21%2C%22s%22%3A668%2C%22_s%22%3A13%7D; _bfa=1.1600831028743.427gzc.1.1600843833503.1600847244099.5.49.10650038368; _bfs=1.30; _bfi=p1%3D290510%26p2%3D290510%26v1%3D49%26v2%3D48; _jzqco=%7C%7C%7C%7C1600831031803%7C1.1555887407.1600831031625.1600849509140.1600849530503.1600849509140.1600849530503.0.0.0.19.19; __zpspc=9.4.1600846262.1600849530.14%232%7Cwww.baidu.com%7C%7C%7C%25E6%2590%25BA%25E7%25A8%258B%7C%23', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', } def get_url(self): while True: content = self.chrome.find_element_by_class_name('right-content-list').get_attribute('innerHTML') cons = re.findall(r'href="(.*?)" title="(.*?)"', content) for con in cons: self.detail_url = 'https:' + con[0] self.title = con[1] print(self.detail_url, self.title) self.get_detail() self.chrome.find_element_by_class_name('u_icon_enArrowforward').click() time.sleep(1) self.page += 1 if self.page == 120: break def get_detail(self): detail_con = requests.get(self.detail_url, verify=False, headers=self.headers).text # time.sleep(2) '''使用正则获取信息''' self.rank = ''.join(re.findall(r'rankText">(.*?)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3