V1.0 教你如何爬取天气数据|超详细

标题意思是:爬虫实践;爬取中国天气网天气数据1.0版本,以后如有更新就不更改原博了(记录一下,免得以后忘了就尴尬了)

编程环境:Pycharm
浏览器:Google Chrome

这个实践大概花了两个小时时间,虽然慢了点但是还是很有成就感的嘿,毕竟第一次写爬虫。
爬虫目标是爬取中国天气网上指定城市的7日天气数据并保存。
思路是模块化编程。
以下具体思路!

第一步:构建url

在中国天气网搜索某城市,观察其url,发现构造并不像搜索引擎一样,但是url主体相同,区别是每个城市有各自的id,所有第一次必须手动去中国天气网查询城市,获得相应id,然后添加到cityID字典里。

第二步:爬取HTML内容

得到url后,就是万用的getHTML模块。以下便是爬虫三连。

        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding

第三步:解析HTML内容

解析HTML获取所需要的数据是爬虫最重要的一步。
而解析HTML的内容就轮到BeautifulSoup上场。
本次实践使用的是CSS语法查找的所需要的元素。

原网页的图示位置右键鼠标,点击检查,得到下图:
在这里插入图片描述
易知我们所需数据的位置。观察标签树,构建搜索语句。

soup = BeautifulSoup(html.text, 'lxml')
l = soup.select('div[id="7d"] input[id="hidden_title"]')
ll = soup.select('ul[class="t clearfix"] li')

如何进一步提取所需数据,过滤无关数据?
!!!re!
依然是观察数据然后构建re表达式来提取数据。

re.findall(r'\d.*C', str(ll)

第四步:保存数据

本来最好是创建一个小型数据库,但是我不太熟练,就简单的放到文本文件里。
一个好的技巧是使用with语句来打开文件,这样可以免去忘了关闭文件导致文件损坏或者丢失等问题。

def saveHTML(s):
    with open(r"climate.txt",'at') as f:
        f.write(s+'\n')

第五步:主程序

for i,j in cityID.items():
    url='http://www.weather.com.cn/weather/'+cityID[i]+'.shtml'
    ls=[]
    HTML=getHTML(url)
    tx=readHTML(HTML)
    tx.pop(1)
    saveHTML(i+':'+str(tx))
    ls.clear()

到这里爬虫已经写完了,但是我无聊又给改造了一下加上了一个进度条,用来提高交互友好度,在爬取大批量数据时可以清晰的知道大概进度。

附加:文本进度条

s ,n= len(cityID),1
print("执行开始".center(s // 2, "-"))
start = time.perf_counter()
for i,j in cityID.items():
	pass
    a ,b= '*' * n,'.' * (s - n)
    print("\r{:^3.0f}%[{}->{}]".format(n*100/s, a, b), end='') 
    n+=1
print('   {:.2f}s\n执行结束!'.format(time.perf_counter() - start))

这个进度条实现的功能是每爬完一个城市,进度条就增加一点,比例是s ,n= len(cityID),1'{:^3.0f}%'.format(n*100/s),然后添加了运行程序的耗时。

突然想到,每个页面的爬取时间大概是一样的,其实貌似还可以添加上‘预期结束时间’和‘预期剩余时间’的,算了,以后有机会再说吧。

就这样,以上。

.

完整算法

# !/usr/bin/ env python
# author:LingInHeart
# time:2019/12/14
# 实践项目-爬取天气预报数据
# 能力所限,只能做到爬取当日所在的7日天气数据,并保存在txt文档里。
# 中国天气网的搜索是用id构建的,没有城市相应的id,只能手动添加id再构造url

from bs4 import BeautifulSoup
import requests
import re,time

cityID={'应城-湖北':'101200405','东港-辽宁':'101070604','裕华-河北':'101090123'}

def getHTML(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r
    except Exception as err:
        print(err)
def readHTML(html):
    soup = BeautifulSoup(html.text, 'lxml')
    ll = soup.select('div[id="7d"] input[id="hidden_title"]')
    ls.append(re.findall(r'\d.*C', str(ll)))
    ll = soup.select('ul[class="t clearfix"] li')
    for i in ll:
        s=''
        for j in i.text:
            if j not in [' ', '\n']:
                s += j
        ls.append(re.findall(r'\d.+/.+℃',s))
    return ls
def saveHTML(s):
    with open(r"climate.txt",'at') as f:
        f.write(s+'\n')

s ,n= len(cityID),1
print("执行开始".center(s // 2, "-"))
start = time.perf_counter()
for i,j in cityID.items():
    url='http://www.weather.com.cn/weather/'+cityID[i]+'.shtml'#;print(url)
    ls=[]
    HTML=getHTML(url)
    tx=readHTML(HTML)
    tx.pop(1)
    saveHTML(i+':'+str(tx))
    ls.clear()
    a ,b= '*' * n,'.' * (s - n)
    print("\r{:^3.0f}%[{}->{}]".format(n*100/s, a, b), end='') 
    n+=1
print('   {:.2f}s\n执行结束!'.format(time.perf_counter() - start))
发布了70 篇原创文章 · 获赞 15 · 访问量 4300

猜你喜欢

转载自blog.csdn.net/Heart_for_Ling/article/details/103545124
今日推荐