python爬虫入门! urllib+bs4快速爬取当前天气信息!???

一、目标

目标很简单,就是爬取陕西省各个城市的天气信息,保存在本地! 话不多说,先来张图看看最终的结果。

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

这就是我们最终希望得到的,这里简单说明一下,大部分天气网站的天气信息可能是图标,图片,或者动图,这些肯定是不能保存在txt文件中的,最终可能的结果如上图所示。在本文最后,会贴出来爬取动态图片的代码,供大家参考交流。

二、安装依赖
1. import urllib.request
urllib是python内置的http请求库,不需要安装直接就可以使用
2. from bs4 import BeautifulSoup
bs4是一个非常简单易用的解析工具,anaconda自带,也可以通过pip下载
3. import datetime
datetime是python自带的时间模块,主要是为了记录爬取的时间信息
三、元素选择简单介绍
  • 我是测试001
  • 我是测试002

如果你写过css,那你一定清楚,如果我们希望定位li标签下的‘我是测试001’和‘我是测试002’。常用的方法是使用标签选择器,id选择器,类选择器等等,不同的选择器可以复合使用。

标签选择器:直接将标签名作为选择器。例如‘div’,即可选择所有div标签下的元素
id选择器:使用‘#’+标签的id名作为选择器,每个标签的id是唯一的不可重复。例如‘#testid’,即可选中id为‘testid’的标签
类选择器:使用‘.’+标签的class作为选择器,不同标签的class可能相同。例
如‘.testclass’,即可选择有calss为‘testclass’的标签
同时,也将不同的选择器组合起来使用,例如上述示例代码中,为了精准定位‘我是测试001’和‘我是测试002’,可以这样写:`#testid .testclass ul li`它的意思是,id是testid标签下的类名为testclass标签下的ul标签下的li标签。bs4可以为我们提供一样的语法来帮我们定位解析爬取下来的文档内容,获取我们想要的信息。这也是为什么bs4简单易用的原因。除了上述的选择器定位元素之外,还有其他的方法诸如:xpath、正则等。

四、分析网页,定位信息
在开始写爬虫之前,我们先分析一下将要爬取的天气网站,看看我们希望得到哪些信息。

?爬虫爬取数据需要注意法律规范,严禁恶意攻击他人网站,或者盗用别人的数据非法盈利
python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

框出来的部分就是我们想要的信息,接着定位我们希望得到的信息。浏览器的控制台可以帮助我们快速定位元素,以谷歌浏览器为例:按下图的步骤操作之后,再在页面上点击自己希望定位的元素。

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

接着按照上面提到的选择器,定位元素即可。以西安为例:首先,我们希望爬取的所有信息都在类名为forecast的div标签下的类名forecastBox的div标签下的dl标签中。城市名在dt标签下的a标签中。(??这里插一嘴,a标签是一个点击之后可以跳转至新页面的标签,新页面的url地址就是a标签上href指定的内容,即点击西安之后,我们就能跳转下面的网页。很显然这个页面是西安天气更加详细的详细信息,urllib可以帮助我们爬取a标签指定的页面的内容。所以我们可以顺便定位分析这个页面的内容,获取更加详细的天气信息。定位的方法大同小异,大家可以自己试试)

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

dd标签下的第一个a标签下有两个img标签,分别对应了白天的天气和夜间的天气,这就是开头提到的不能保存在txt文件中的图片,只能存下来图片的路径了(网站中有专门介绍天气图标的页面)

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

dd标签下的第二个a标签和第三个a标签下面的span标签则是今日的最高气温和最低气温细心的伙伴可能会发现,存在很多个dl标签,这就是写法规范的网站,陕西省下面的其他城市都和西安是类似的,这其实也为我们提供了便利,使用bs4定位的时候,会直接把所有城市的数据都解析出来,存在一个列表里。

五、爬虫实现
  1. 引入依赖
    import urllib.request from bs4 import BeautifulSoup import datetime

  2. 获取当前时间,写入文件
    now_time = datetime.datetime.now() time1_str = datetime.datetime.strftime(now_time,'%Y-%m-%d %H:%M:%S') fl = open(r'陕西省天气信息.txt',"a+",encoding='utf-8') fl.write("抓取时间:"+time1_str) fl.write('\n') fl.close()

主要是python的文件操作,这里小小偷个懒,大家自己search吧
  1. 爬取文档
    url="http:/testt/test.shtml"#示例url,并不真实存在 response=urllib.request.urlopen(url) d=response.read() soup=BeautifulSoup(d,"lxml")

python内置的urllib下的request模块的urlopen使用GET方式对网站发起请求
urlopen返回的response对象是http.client.HTTPResponse类型,主要包含read()、readinfo()、getheader(name)、getheaders()、fileno()等方法。
使用BeautifulSoup对文档解析,第一个参数是要解析的文档内容,第二个参数声明解析的方式,一般lxml已经足够使用了。具体的信息网上有很多,这里继续偷懒
  1. 解析元素
ls_Url_Name = soup.select('.forecastBox dl dt a') ls_WeatherInfo = soup.select('.forecastBox dl dd a img') ls_MinTem = soup.select('.forecastBox dl dd a b') ls_TopTem = soup.select('.forecastBox dl dd a span')

使用select可以按照上面介绍的选择器快速访问标签
ls_Url_Name是一个存放每个城市名a标签的列表
ls_WeatherInfo是存放每个城市白天气温和夜间气温img标签的列表
ls_MinTem是存放每个城市最低气温的列表
ls_TopTem是存放每个城市最高气温的列表
PS:最低气温和最高气温虽然解析了,但是并没有写入文件中,这里打印一下,让大家看看解析出来的列表长什么样子

python爬虫入门! urllib+bs4快速爬取当前天气信息!???
文章图片

  1. 遍历列表、组装信息
    j=0 for i in range(0,len(ls_Url_Name)): str1 = "" str1 = str1 + ls_Url_Name[i].get_text()+"\n" str1 = str1 + "白天天气信息:" + ls_WeatherInfo[j].attrs['src'] + "" str1 = str1 + "夜晚天气信息:" + ls_WeatherInfo[j+1].attrs['src'] + "\n" j+=2

这里就用最简单字符串拼接的方法来组装我们需要的信息。
有了上述标签列表,bs还提供了一些方法帮助我们获取标签中的信息
get_text()可以获取标签中的文本信息
PS:声明一个j变量,每次循环的时候j的步数应该是2,因为每个城市有白天和夜晚两个气温

  1. 获取a标签的href,进去详情页面
    url = ls_Url_Name[i].attrs['href'] response=urllib.request.urlopen(url) d=response.read() soup=BeautifulSoup(d,"lxml") str1 = str1 + "当前天气信息:" + soup.select('.c7d ul li .wea')[0].get_text() + "\n" str1 = str1 + "当前气温:" + soup.select('.c7d ul li .tem')[0].get_text() str1 = str1 + "当前风向:" + soup.select('.c7d ul li .win em span')[0].attrs['title'] + "" + "当前风速:" + soup.select('.c7d ul li .win i')[0].get_text() + '\n' print(str1)

    bs解析出的标签的attrs中包含了元素的各个属性,我们要得到的就是a标签的href属性
获得详情页面的url之后,和之前的操作方法相同,请求详情页面,解析元素,获得我们需要的信息,组装字符串,最后写进文件即可

附上遍历列表的完整代码
j=0 for i in range(0,len(ls_Url_Name)): str1 = "" str1 = str1 + ls_Url_Name[i].get_text()+"\n" str1 = str1 + "白天天气信息:" + ls_WeatherInfo[j].attrs['src'] + "" str1 = str1 + "夜晚天气信息:" + ls_WeatherInfo[j+1].attrs['src'] + "\n" j+=2 url = ls_Url_Name[i].attrs['href'] response=urllib.request.urlopen(url) d=response.read() soup=BeautifulSoup(d,"lxml") str1 = str1 + "当前天气信息:" + soup.select('.c7d ul li .wea')[0].get_text() + "\n" str1 = str1 + "当前气温:" + soup.select('.c7d ul li .tem')[0].get_text() str1 = str1 + "当前风向:" + soup.select('.c7d ul li .win em span')[0].attrs['title'] + "" + "当前风速:" + soup.select('.c7d ul li .win i')[0].get_text() + '\n' print(str1) fl = open(r'陕西省天气信息.txt',"a+",encoding='utf-8') fl.write(str1) fl.write('\n') fl.close()

【python爬虫入门! urllib+bs4快速爬取当前天气信息!???】
附:爬取天气图标
import osls = soup.select('.forecastBox dl dd a img') j=1#爬取天气图标测试 for i in ls: str1 = i.attrs['src'] str1 = page1 + str1 if os.path.exists("D:/imags") == False: os.mkdir("D:/imags") bytes = urllib.request.urlopen(str1) str3 = "D:/imags/test"+str(j)+'.gif' f = open(str3,'wb') f.write(bytes.read()) f.flush() f.close() j+=1

为了防止一些坏人恶意高频率访问人家的网站,这里就不提供网站的地址了,大家可以自己找一些网站自己操作。在未告知对方的前提下,获得的数据切记不得私自用于盈利,不能影响别人呦。 最近疫情非常严重,尤其是上海,希望我们的祖国能够尽快战胜疫情,大家一定做好防护,祝大家身体健康

    推荐阅读