当前位置: 首页 > 科技观察

完美假期的第1步:使用Python查找更便宜的航班!

时间:2023-03-18 15:08:06 科技观察

大叔文摘制作编译:高燕、熊燕、胡佳、蒋宝尚《你喜欢旅行吗?这个简单的问题往往会得到肯定的答复,甚至还会收到一两个额外的冒险故事。一般来说,旅行是体验新文化和开阔视野的好方法。但是如果把问题换成“你喜欢查机票的过程吗?”,相信大家的反应会不那么热情了……所以,用Python来解决你的难处吧!本文作者FábioNeves是一位经验丰富的商业数据分析师,他将带您构建网络爬虫项目,帮助我们找到最划算的交易!这是通过飞往具有灵活日期范围的特定目的地(最多在您选择的日期之前或之后3天)价格搜索来完成的。搜索结果保存到excel中,并向您发送一封显示快速统计信息的电子邮件。显然,最终目标是帮助我们找到最好的价格!如果你真的想试试,你可以在服务器上执行这个脚本(一个简单的树莓派就可以了(注:树莓派也叫卡片式计算机,形状只有信用卡大小,计算性能和智能手机差不多。所以大家在笔记本电脑上折腾一下就够了。。)),一天跑一两次就够了。它会将搜索结果通过电子邮件发送给您,我建议将excel文件保存到Dropbox云端,这样您就可以随时随地访问它。注:Dropbox是一个类似百度云的云服务便宜票我还是查不出什么毛病,不过估计还是可以的!它将通过“灵活的日期范围”进行搜索,以在您的首选日期之前或之后查找最多3个当天的所有航班。尽管该脚本一次仅适用于一组起点/终点目的地,但您可以轻松调整它以在每个循环中运行多组旅行目的地。您甚至可能最终会找到一些错误票……太棒了!爬行脚本当我第一次开始进行网络爬行时,我对这个领域并不是特别感兴趣。我本来想做更多带有预测建模、财务分析和一些情绪分析的项目,但结果发现弄清楚如何构建我的第一个网络爬虫很有趣。随着我继续学习,我意识到网络抓取是互联网运作方式的本质。是的...就像Larry和Sergey一样,在启动爬行器后去按摩浴缸宠爱自己!您可能认为这是一个非常大胆的想法,但是如果我告诉您Google是由Larry和Sergey诞生的,那么用Java和Python编写的机器人呢?Google会抓取整个互联网,尝试为您的问题提供最佳答案。Web抓取的应用非常多,即使你更喜欢数据科学中的其他主题,你仍然需要一些抓取技巧来获取你想要的数据。Python可以助您一臂之力第一个挑战是选择从哪个平台抓取信息。这并不容易,但我最终选择了Kayak。在决定之前,我尝试了Momondo、Skyscanner、Expedia等,但这些网站上的验证码部分真的让人抓狂。在多次尝试选择交通灯、人行横道和自行车的“你是真的吗”检查之后,我得出结论,Kayak是迄今为止最好的选择,即使它在短时间内加载太多页面时会失败.检查安全性。我将机器人设置为每隔4到6小时查询一次站点,所以这应该不是问题。偶尔会有卡住的中断,但是如果你得到了验证码验证,那么你需要手动进行验证码验证,然后启动机器人,然后等待几个小时让它重置。您也可以自由地将这些代码应用到其他平台,欢迎您在评论区分享您的应用!如果你刚接触抓取,或者不明白为什么有些网站总是设置各种障碍来阻止网页抓取,那么在编写你的第一行抓取代码之前,请阅读谷歌的“WebScrapingEtiquette”。如果您准备好像疯子一样开始网络抓取,您可能会比您想象的更快地获得努力的成果。Web抓取礼仪:http://lmgtfy.com/?q=web+scraping+etiquette系好安全带...打开chrome选项卡后,我们将定义一些要在循环内使用的函数。总体结构的总体思路是:一个函数将启动机器人,说明我们要搜索的城市和日期。此功能获取第一个搜索结果并按“最佳”航班对它们进行排序,然后单击“加载更多结果”。另一个函数将获取整个页面并将返回一个数据框数据集重复步骤2和3以获得“最便宜”和“最快”的排序结果。将价格(最便宜和平均)的最终结果通过电子邮件发送给您,并将三个排序的(价格、时间、最佳整体)数据集保存为excel文件所有前面的步骤都在一个循环中重复,每隔X每小时运行一次。好的,每个Selenium项目都将从webdriver开始。我使用的是ChromeDriver,当然还有其他选择。例如,PhantomJS或Firefox也很流行。webdriver下载好之后,放到一个文件夹里就可以了。第一行代码会自动打开一个空白的Chrome标签页。请注意,我不是在这里开辟新天地,也不是提出非常具有突破性的创新。确实有更高级的方法可以找到便宜的票价,但我希望我的这篇文章能分享一些简单实用的东西!这些是我为整个项目引用的包。我将使用randint让机器人在每次搜索之间随机暂停几秒钟。这是所有机器人必备的功能。如果你已经运行了前面的代码,你需要打开一个Chrome网页窗口作为机器人搜索的入口。因此,让我们先在新网页中打开kayak.com进行快速测试。选择您要飞往的城市和日期。选择日期时,一定要选择“+-3天”。我写了相关的代码,如果你只想搜索特定的日期,那么你需要做一些适当的调整。我会尽量在全文中指出所有的变量值。点击搜索按钮并在地址栏中获取链接。这个链接应该是我下面需要用到的链接,这里我定义变量kayak为url,调用webdriver的get方法。接下来应该会出现您的搜索结果。每当在短时间内多次使用get命令时,系统就会跳出验证码校验。您可以手动解决验证码问题并在下一个问题出现之前继续测试您的脚本。从我的测试来看,第一次搜索运行似乎工作正常,所以如果你想使用这段代码,并让它们在执行之间保持较长的间隔执行,你可以解决这个问题。您不需要每10分钟更新一次这些价格,对吗?!XPath的坑至此,我们打开了一个浏览器窗口,得到了URL。接下来我将使用XPath或CSS选择器来获取价格和其他信息。我以前只使用XPath。当时觉得没必要用CSS,现在看来还是结合使用比较好。可以直接用浏览器复制网页的XPath,同时你也会发现虽然XPath可以定位网页元素,但是可读性很差,所以我渐渐发现很难获取到你想要的页面元素只有XPath。有时,指向越精细,它的用处就越小。接下来,我们使用Python来选择票价最低的页面元素。上面代码中红色部分是XPath选择器的代码。在网页中,可以在任意位置右击选择“Inspect”进行查找。试一试,右键单击要查看代码的位置并“检查”它。为了解释我前面提到的缺少XPath,请比较以下差异:1#Thisiswhatthecopymethodwouldreturn.Rightclickhighlightedrowsontherightsideandselect"copy>CopyXPath"//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/span2#ThisiswhatIusedtodefinethe"Cheapest"buttoncheap_results='//a[@data-code="price"]'在上面的代码中,第二种方法的简单性显而易见。它搜索具有data-code属性值price的a元素。第一种方法是搜索一个id为wtKI-price_aTab的元素,这个元素嵌入在一个5层的div和一个2层的span中。对于这个页面,是可以的,但是这里的坑是下次加载页面的时候id会变,而且每次加载的时候wtKI的值也是动态变化的,所以这时候这段代码就失效了。因此,多花一点时间研究XPath代表什么对您来说仍然很有价值。不过这种直接复制XPath的方法对于那些不是很复杂和多变的页面还是比较好用的。根据上面的代码结果,如果想把所有匹配的结果都找出来,存入列表中怎么办?很简单,因为所有的结果都在CSS对象resultWrapper中,只要按照下图的代码写一个for循环就可以得到所有的结果。掌握了这个思路之后,你就可以基本看懂下图中的代码了。也就是说,首先选择最外层的页面元素(比如本文网站中的resultWrapper),然后想办法(比如XPath)获取信息,最后将信息存储在一个可读对象中(本例中先存储在flight_containers中,然后存储在flights_list中)。我打印出了前三个结果的详细信息,其中包含了我们需要的所有有用信息,但我们仍然需要找到更好的方法来提取它们,然后我们必须分别解析这些元素。开始爬取数据!最简单的代码就是阅读更多这个功能,让我们从这里开始。我想在不触发安全检查的情况下获得尽可能多的航班,所以每次加载页面时我都单击“加载更多结果”按钮。值得注意的是我使用了try语句,因为有时候这个按钮不一定存在。哦,前期有点长(抱歉,我确实容易跑偏)。我们现在要定义爬取数据的函数。我解析了下面提到的page_scrape函数中的大部分元素。有时,返回的航班列表中会出现两个行程。我简单的把它拆分成了两个变量,比如section_a_list和section_b_list。当然,该函数仍然会返回一个名为flights_df的DataFrame对象,然后我们可以根据需要对其进行排序、切片或合并。变量名中带a的代表第一阶段旅行,带b的代表第二阶段旅行。然后看下一个函数。但是等等,还有更多!到目前为止,我们有用于加载更多结果的函数,以及用于解析这些结果的函数。你可以认为这就结束了,你可以依靠他们手动爬网,但正如我前面提到的,我们的目标是能够给自己发电子邮件,当然还包括一些其他信息。看看下面的start_kayak函数,所有这些都在里面。这就需要我们定义好要查询的航班的地点和日期。我们将打开kayak变量中的URL,查询结果会直接按“best”排序。第一次爬取后,我得到了页面顶部的价格矩阵数据集,将用于计算平均和最低价格,然后与Kayak的预测价格(页面左上角)一起通过电子邮件发送。这可能会导致搜索单个日期时出错,因为在这种情况下页面顶部没有价格矩阵。我用outlook邮箱(hotmail.com)做了一个测试。虽然没试过Gmail,甚至还有其他各种邮箱,不过我觉得应该没问题。而我前面提到的那本书也写了其他发送邮件的方法。如果你有hotmail邮箱,直接在代码中替换你的邮箱信息就可以了。如果你想知道脚本中某一部分代码做了什么,你必须把那部分代码复制出来测试一下,因为只有这样你才能完全理解它。运行代码当然,我们也可以把前面写的函数放到一个循环中,让它一直运行。写下4个输入提示,包括起飞降落城市和起止时间(输入)。但是在测试的时候,我们不想每次都输入这四个变量,所以我们直接修改这四个变量,如注释的四行代码所示。恭喜大家,到目前为止我们已经完成了!其实还有很多可以改进的地方。例如,我能想到的是,Twilio可以用来发送短信而不是电子邮件。您还可以设置VPN或其他隐蔽方式同时通过多台服务器抓取数据。还有验证码问题,它们总是不时弹出,但有办法解决。如果你基础比较好,我觉得你可以尝试加入这些功能。您甚至可能希望将Excel文件作为电子邮件附件发送。相关报道:https://towardsdatascience.com/if-you-like-to-travel-let-python-help-you-scrape-the-best-fares-5a1f26213086【本文为栏目组织大佬原创文章数据文摘微信公众号《大数据文摘(id:BigDataDigest)》】点此查看作者更多好文