高温来袭?通过python爬虫爬取天气预警信息

需求分析

最近一段时间,天气也是越来越热了,真正的进入了夏天了。可怕的故事是,现在才只有6月份呢,要是等到了7,8月份,不会是要更热吧?

一个小伙伴对此也深表赞同,“仙草哥哥,现在天气的温度这么高,我们必须要做好应对措施,不然疏于防范,一下子中暑了可就不好了。仙草哥哥,你能不能做一个爬虫程序,爬取天气预警信息呢?不仅能够提前预防高温,有什么狂风暴雨之类的,也能提前做好准备,我觉得这个有用!”

既然小伙伴都这么建议了,我们就安排上,通过爬虫程序,爬取天气预警信息

页面分析

通过观察这个页面的话,初步判断这个程序应该是挺简单的,如下所示

 内容很清晰,而且明了,主要只要获取到预警信息,和时间就可以了。那么如果不出意外的话,还是和往常一样,通过requests发起请求,再通过xpath进行解析就可以完成了,没什么困难的,那么就直接开始吧

实现分析

虽然这个需求看起来很容易,但是真的做起来的时候却发现遇到了一些问题,主要的原因在于

 在html的页面中并没有数据,而是一些选项,真正的数据是通过js拼接起来的,所以我们通过requests请求并不能获取到数据,除非我们按照js规则,重新进行预警的拼接,这可不是一件容易的事情,为了不要这么麻烦,我们应该采取一点容易的行为,换成使用selenium即可

那么,我们只能放弃了原本使用requests的想法,改为使用selenium

driver = webdriver.Chrome()
driver.get(url)

print(driver.page_source)

selenium的使用并不困难,我们只需要打开一个浏览器,发起get请求即可,然而奇怪的事情发生了,selenium里面居然也没有数据,这是怎么回事?太不可思议了吧,这怎么可能呢?

观察selenium返回的源代码,我们发现得到的结果仍然是不完整的,这是怎么一回事呢?有一瞬间我甚至怀疑自己是不是搞错了,可这不可能啊,selenium怎么可能返回未执行js的结果呢?

于是,我重新返回了页面进行观察,果然不出所料,我看到了这个

 原来是一个iframe标签,那就难怪刚刚没有得到结果了。iframe的标签在使用selenium的时候要特别注意,因为要进行一次切换以后才能够得到数据,所以,首先我们切换到iframe里面,这个问题就解决了

# 切换到iframe的标签中
driver.switch_to.frame(driver.find_element(by="xpath", value="//iframe"))

可以看到,这里我们使用了selenium的“新”方法,find_element,对于有经验的selenium的老使用者,一定记得以前通过selenium寻找元素的时候,都是使用的find_element_by_xxx,但是后来版本更新,现在要求不要再使用老的方法了,而是使用这种新的方法find_element

虽然老的方法和新的方法没有很多区别,应该改为新方法也没什么困难的,但是俗话说,习惯成自然,比如说在这里获取元素的时候,我们还是非常容易写成老的find_element_by_xpath,而不记得现在新的方法应该怎么写,这也是很正常的,所以说,这种用了很久的接口调整一定要小心谨慎。如果随意更换接口,就会给用户带来很大的困难和麻烦,甚至是以前写的代码在新的版本中都将不能使用了,这不是一件好的事情

当然,事实上,如果不通过find_element提取数据,只是通过其获取元素的话,其实使用find_element的频率也没有那么高,我们完全可以把page_source直接交给xpath处理,不一定非要通过find_element来获取数据。这也是一种办法

总之,至此,所有的困难我们都已经解决了,应该可以顺利的拿到数据了

完整代码展示

import base64
from selenium import webdriver
from lxml import etree

driver = webdriver.Chrome()
driver.get(base64.b64decode("aHR0cDovL3d3dy53ZWF0aGVyLmNvbS5jbi9hbGFybS9hbGFybV9saXN0LnNodG1s").decode())
driver.switch_to.frame(driver.find_element(by="xpath", value="//iframe"))

for i in etree.HTML(driver.page_source).xpath("//ul[@class='dDUl']/li"):print(i.xpath("./span[2]/text()")[0], ":", i.xpath("./a[2]/text()")[0])
driver.quit()

以下是程序运行结果展示


看到这里啊,有些小伙伴可能会非常困惑,“你讲了这么多,总共代码才8行,是不是写爬虫程序特别简单啊?我看都没多少代码的啊!”

这样说也对,这确实是非常简单的一个小功能,代码行数也不多。但是从实现上来说,首先不能使用requests要改为使用selenium,其次直接使用selenium请求地址拿不到数据,要切换一次标签。所以实现的过程中还是遇到了一点小麻烦,并没有看起来那么容易

总之,程序就是这样,难易程度其实不是看代码的多少来决定的,而要看需求和实现

来源:仙草哥哥

物联沃分享整理
物联沃-IOTWORD物联网 » 高温来袭?通过python爬虫爬取天气预警信息

发表评论