爬取某城市一个月内的天气情况

前段时间面试了伊利集团,领导现场出题,让我爬取天气网站上的城市降水量,这里我做了一个简单的爬取呼和浩特市一个月内的天气情况的爬虫小程序,最终结果是保存在一个txt文件夹中,感兴趣的各位可以参考一下。(当然程序我也是参考了别人的,嘿嘿嘿!!)
爬虫的整体原理可以参考我的上一篇博客,是我从b站上看视频做的一点总结,想快速上手爬虫的小伙伴快来!!

程序底层框架
(一)导入所需库
这里我们导入需要的第三方库和内库

  1. requests
    这个是第三方库,需要自行安装,pip一下,它主要用来发送请求
  2. re
    这是一个内库,即标准库,是python自带的,无需手动安装,主要作用就是正则表达式提取html文档时用到
  3. BeautifulSoup
    相当于一个解析器,也是在html文档解析时用到,作用和XPath类似
  4. pandas
    第三方库,非常强大,常用于做数据分析,可以提供一些处理数据的函数和方法,创建DataFrame时用

(二)获取天气网页的url
我们先来说一下什么是网络资源,其实网络资源就是我们看到的任何一张图片,文字信息、视频、音频等等都可以称作一个网络资源。我们在浏览器搜索就需要它对应的网址,每一种网络资源都可以用一个url来命名。现在做的就是需要爬取天气信息,所以首先要有天气网页的URL,headers这是一个请求头,可设可不设,请求头是怕服务器有反爬机制,拒绝爬虫的发送的请求,设置请求头就是为让服务器认为是浏览器在访问,发现不了是爬虫。
(三)获取网页源代码——html文档
我们将网页源代码下载下来,进行源码提取,在此之前还需要对其进行一个文本格式的转换

(四)正则解析提取所需内容
我们将网页源码打开之后,找到我们要爬取的内容所在节点,然后用正则提取即可。
我们要记住正则提取的一个常用框架,re.findall(r’从哪里开始 (.*?) 到哪里结束’,html,re.s)[0] .代表匹配任意字符,*代表匹配多个,?代表非他能匹配,()代表反向捕获

(五)将结果导入到txt文件中

具体代码

import requests
import re
import time
from bs4 import BeautifulSoup
import pandas as pd

url='http://lishi.tianqi.com/huhehaote/202110.html'

headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
            'Cookie':'lianjia_uuid=9d3277d3-58e4-440e-bade-5069cb5203a4; UM_distinctid=16ba37f7160390-05f17711c11c3e-454c0b2b-100200-16ba37f716618b; _smt_uid=5d176c66.5119839a; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2216ba37f7a942a6-0671dfdde0398a-454c0b2b-1049088-16ba37f7a95409%22%2C%22%24device_id%22%3A%2216ba37f7a942a6-0671dfdde0398a-454c0b2b-1049088-16ba37f7a95409%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; _ga=GA1.2.1772719071.1561816174; Hm_lvt_9152f8221cb6243a53c83b956842be8a=1561822858; _jzqa=1.2532744094467475000.1561816167.1561822858.1561870561.3; CNZZDATA1253477573=987273979-1561811144-%7C1561865554; CNZZDATA1254525948=879163647-1561815364-%7C1561869382; CNZZDATA1255633284=1986996647-1561812900-%7C1561866923; CNZZDATA1255604082=891570058-1561813905-%7C1561866148; _qzja=1.1577983579.1561816168942.1561822857520.1561870561449.1561870561449.1561870847908.0.0.0.7.3; select_city=110000; lianjia_ssid=4e1fa281-1ebf-e1c1-ac56-32b3ec83f7ca; srcid=eyJ0Ijoie1wiZGF0YVwiOlwiMzQ2MDU5ZTQ0OWY4N2RiOTE4NjQ5YmQ0ZGRlMDAyZmFhODZmNjI1ZDQyNWU0OGQ3MjE3Yzk5NzFiYTY4ODM4ZThiZDNhZjliNGU4ODM4M2M3ODZhNDNiNjM1NzMzNjQ4ODY3MWVhMWFmNzFjMDVmMDY4NWMyMTM3MjIxYjBmYzhkYWE1MzIyNzFlOGMyOWFiYmQwZjBjYjcyNmIwOWEwYTNlMTY2MDI1NjkyOTBkNjQ1ZDkwNGM5ZDhkYTIyODU0ZmQzZjhjODhlNGQ1NGRkZTA0ZTBlZDFiNmIxOTE2YmU1NTIxNzhhMGQ3Yzk0ZjQ4NDBlZWI0YjlhYzFiYmJlZjJlNDQ5MDdlNzcxMzAwMmM1ODBlZDJkNmIwZmY0NDAwYmQxNjNjZDlhNmJkNDk3NGMzOTQxNTdkYjZlMjJkYjAxYjIzNjdmYzhiNzMxZDA1MGJlNjBmNzQxMTZjNDIzNFwiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCIzMGJlNDJiN1wifSIsInIiOiJodHRwczovL2JqLmxpYW5qaWEuY29tL3p1ZmFuZy9yY28zMS8iLCJvcyI6IndlYiIsInYiOiIwLjEifQ=='
            }

def get_page(url,headers):
    html=requests.get(url,headers=headers)
    # HTTP状态码(baiHTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码,200表示请求成功:表示网络请求成功的意思
    if html.status_code==200:
        html.encoding=html.apparent_encoding   # apparent_encoding会从网页的内容中分析网页编码的方式,所以apparent_encoding比encoding更加准确
        return html.text
    else:
        return None

# 因为要爬取该城市11月份每天的'星期':week_box,'最高温度':max_temp,'最低温度':min_temp,'天气':weh,'风向':wind,创建对应的空列表去存储信息
date_box=[]
max_temp=[]
min_temp=[]
weh=[]
wind=[]
week_box=[]

html=get_page(url,headers)
# 解析数据,这里用到BeautifulSoup,我们也可以用XPath里的lxml,使用BeautifulSoup前需要先构建BeautifulSoup实例(需要补充一下)
bs=BeautifulSoup(html,'html.parser')
# find_all方法返回所有匹配到的结果
data=bs.find_all(class_='thrui')
# re.compile()生成的是正则对象,单独使用没有任何意义,需要和findall(), search(), match()搭配使用。re.compile()是用来优化正则的,它将正则表达式转化为对象,re.search(pattern, string)的调用方式就转换为 pattern.search(string)的调用方式,多次调用一个正则表达式就重复利用这个正则对象,可以实现更有效率的匹配
date=re.compile('class="th200">(.*?)</')  # 利用正则唯一把日期提取出来
tem=re.compile('class="th140">(.*?)</')  # 把最高、底气温、天气、风向提取出来
# compile和finall结合可以输出一个列表,tem就是一个列表
# findall可以实现从字符串文本中提取日期,正好日期是字符串格式
time=re.findall(date,str(data))
# 用一个for循环把这个月的对应日期是周几列出来,并把值填进之前建立的空列表中
for item in time:
    week=item[10:]
    # 在week_box列表末尾追加新对象,即把值填进之前建立的空列表中
    week_box.append(week)
    date_box.append(item[:10])
temp=re.findall(tem, str(data))   #返回string中所有与pattern相匹配的全部字串,返回形式为数组
# 用一个for循环,将10月份每天对应的数据追加填进空列表中,数组下表从0开始,首先i取0
for i in range(31):
    max_temp.append(temp[i*4+0])  # temp是一个数组,当i取0时,temp取0,temp[0]就是最高气温
    min_temp.append(temp[i*4+1])
    weh.append(temp[i*4+2])
    wind.append(temp[i*4+3])
# 创建DataFrame,对应的语法就是 列名:行索引
datas=pd.DataFrame({'日期':date_box,'星期':week_box,'最高温度':max_temp,'最低温度':min_temp,'天气':weh,'风向':wind})
print(datas)
# 将其导入txt文件中
datas.columns=['日期','星期','最高温度','最低温度','天气','风向']
datas.to_csv('tianqi.txt')

运行结果
将运行结果保存在tianqi.txt这个文件夹中,如果路径没有会自行创建
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值