一、目标
目标很简单,就是爬取陕西省各个城市的天气信息,保存在本地!
话不多说,先来张图看看最终的结果。
文章图片
这就是我们最终希望得到的,这里简单说明一下,大部分天气网站的天气信息可能是图标,图片,或者动图,这些肯定是不能保存在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、正则等。
四、分析网页,定位信息
在开始写爬虫之前,我们先分析一下将要爬取的天气网站,看看我们希望得到哪些信息。
?爬虫爬取数据需要注意法律规范,严禁恶意攻击他人网站,或者盗用别人的数据非法盈利
文章图片
框出来的部分就是我们想要的信息,接着定位我们希望得到的信息。浏览器的控制台可以帮助我们快速定位元素,以谷歌浏览器为例:按下图的步骤操作之后,再在页面上点击自己希望定位的元素。
文章图片
文章图片
接着按照上面提到的选择器,定位元素即可。以西安为例:首先,我们希望爬取的所有信息都在类名为forecast的div标签下的类名forecastBox的div标签下的dl标签中。城市名在dt标签下的a标签中。(??这里插一嘴,a标签是一个点击之后可以跳转至新页面的标签,新页面的url地址就是a标签上href指定的内容,即点击西安之后,我们就能跳转下面的网页。很显然这个页面是西安天气更加详细的详细信息,urllib可以帮助我们爬取a标签指定的页面的内容。所以我们可以顺便定位分析这个页面的内容,获取更加详细的天气信息。定位的方法大同小异,大家可以自己试试)
文章图片
dd标签下的第一个a标签下有两个img标签,分别对应了白天的天气和夜间的天气,这就是开头提到的不能保存在txt文件中的图片,只能存下来图片的路径了(网站中有专门介绍天气图标的页面)
文章图片
dd标签下的第二个a标签和第三个a标签下面的span标签则是今日的最高气温和最低气温细心的伙伴可能会发现,存在很多个dl标签,这就是写法规范的网站,陕西省下面的其他城市都和西安是类似的,这其实也为我们提供了便利,使用bs4定位的时候,会直接把所有城市的数据都解析出来,存在一个列表里。
五、爬虫实现
- 引入依赖
import urllib.request from bs4 import BeautifulSoup import datetime
- 获取当前时间,写入文件
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吧
- 爬取文档
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已经足够使用了。具体的信息网上有很多,这里继续偷懒
- 解析元素
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:最低气温和最高气温虽然解析了,但是并没有写入文件中,这里打印一下,让大家看看解析出来的列表长什么样子
文章图片
- 遍历列表、组装信息
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,因为每个城市有白天和夜晚两个气温
- 获取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
为了防止一些坏人恶意高频率访问人家的网站,这里就不提供网站的地址了,大家可以自己找一些网站自己操作。在未告知对方的前提下,获得的数据切记不得私自用于盈利,不能影响别人呦。 最近疫情非常严重,尤其是上海,希望我们的祖国能够尽快战胜疫情,大家一定做好防护,祝大家身体健康
推荐阅读
- Python爬虫|每日一练(Python爬虫爬取全国新冠肺炎疫情数据实例详解,使用beautifulsoup4库实现)
- Python爬虫|python爬虫(网易新冠疫情数据爬取(一))
- Python地图绘制|每日一练(Python国内疫情数据爬取与地图绘制)
- python|Python爬取网易云音乐网易云音乐歌手歌曲和歌单,并下载到本地
- python爬虫(四)---scrapy框架之腾讯招聘项目实战
- Python爬虫|逆向系列 | AES逆向加密案例分析
- python爬虫|关于使用python 动态爬虫Selenium 下载文件,文件类型的设置
- 教你如何使用Python破解WIFI密码
- python爬虫|【python爬虫教程】请求模块urllib的基本使用