Python爬取哈尔滨天气信息实战:基于Requests与BeautifulSoup
本文提供使用Python爬取哈尔滨天气信息的完整代码示例。环境基于Windows7与Python3.4,需安装requests和BeautifulSoup4库。文章详细解析了open函数的file、mode、buffering、encoding、errors及newline等参数用法,并附带可执行的爬虫代码,涵盖获取HTML、解析数据及写入CSV文件的全过程,适合Python初学者参考学习。
本文分享了利用Python抓取哈尔滨天气数据的具体实现代码,供读者参考与学习。
运行环境配置如下:
操作系统为Windows7。
Python版本为3.4,需通过pip安装requests库和BeautifulSoup4库(命令:pip install requests;pip install BeautifulSoup4)。
具体代码实现如下(经测试可正确执行):
# coding:utf-8
"""
总结一下,从网页上抓取内容大致分3步:
1、模拟浏览器访问,获取html源代码
2、通过正则匹配,获取指定标签中的内容
3、将获取到的内容写到文件中
"""
import requests # 用来抓取网页的html源代码
import csv # 将数据写入到csv文件中
import random # 取随机数
import time # 时间相关操作
import socket # 用于异常处理
import http.client # 用于异常处理
from bs4 import BeautifulSoup # 用来代替正则式取源码中相应标签中的内容
# 获取网页中的html代码
def get_content(url, data=None):
header = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
timeout = random.choice(range(80, 180)) # timeout是设定的一个超时时间,取随机数是因为防止被网站认定为网络爬虫
while True:
try:
rep = requests.get(url, headers=header, timeout=timeout)
rep.encoding = 'utf-8' # rep.encoding = ‘utf-8'是将源代码的编码格式改为utf-8
break
except socket.timeout as e:
print('3:', e)
time.sleep(random.choice(range(8, 15)))
except socket.error as e:
print('4:', e)
time.sleep(random.choice(range(20, 60)))
except http.client.BadStatusLine as e:
print('5:', e)
time.sleep(random.choice(range(30, 80)))
except http.client.IncompleteRead as e:
print('6:', e)
time.sleep(random.choice(range(5, 15)))
return rep.text
# 获取html中我们所需要的字段
def get_data(html_text):
final = []
bs = BeautifulSoup(html_text, "html.parser") # 创建BeautifulSoup对象
body = bs.body # 获取body部分
data = body.find('div', {'id': '7d'}) # 找到id为7d的div
ul = data.find('ul') # 获取ul部分
li = ul.find_all('li') # 获取所有的li
for day in li: # 对每个li标签中的内容进行遍历
temp = []
date = day.find('h1').string # 找到日期
temp.append(date) # 添加到temp中
inf = day.find_all('p') # 找到li中的所有p标签
temp.append(inf[0].string, ) # 第一个p标签中的内容(天气状况)加到temp中
if inf[1].find('span') is None:
temperature_highest = None # 天气预报可能没有当天的最高气温(到了傍晚,就是这样),需要加个判断语句,来输出最低气温
else:
temperature_highest = inf[1].find('span').string # 找到最高温
temperature_highest = temperature_highest.replace('℃', '') # 到了晚上网站会变,最高温度后面也有个℃
temperature_lowest = inf[1].find('i').string # 找到最低温
temperature_lowest = temperature_lowest.replace('℃', '') # 最低温度后面有个℃,去掉这个符号
temp.append(temperature_highest) # 将最高温添加到temp中
temp.append(temperature_lowest) # 将最低温添加到temp中
final.append(temp) # 将temp加到final中
return final
# 写入文件csv
def write_data(data, name):
file_name = name
with open(file_name, 'a', errors='ignore', newline='') as f:
f_csv = csv.writer(f)
f_csv.writerows(data)
if __name__ == '__main__':
url = 'http://www.weather.com.cn/weather/101050101.shtml'
html = get_content(url)
result = get_data(html)
write_data(result, 'weather.csv')
代码逻辑与关键函数讲解:
Python标准库中内置的open函数,其签名通常为open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None...)。
该函数的主要作用是打开指定文件并返回文件对象;若文件无法打开,则抛出OSError异常。
参数file用于指定文件名或文件路径,可以是相对当前目录的路径字符串,也可以是绝对路径字符串。
参数mode用于定义打开文件的具体模式。
1)'r'模式表示以只读方式打开文件,不允许写入操作。
2)'w'模式表示以只写方式打开文件,若文件已存在则先清空文件内容。
3)'x'模式表示独占打开文件,若文件已存在或已被其他进程打开,则操作失败。
4)'a'模式表示以追加方式打开文件进行写入,不清空原有内容,新内容写入文件末尾。
5)'b'模式表示以二进制方式打开文件。
6)'t'模式表示以文本方式打开文件,这也是默认的模式。
7)'+'模式表示打开文件用于更新(即同时支持读取和写入)。
8)若未指定mode,默认等同于'rt'模式。例如'w+b'表示以读写模式打开并清空文件;'r+b'表示以读写模式打开但不清空文件。
参数buffering用于指定缓冲策略,为可选参数。设为0时不使用缓冲区,直接读写,仅在二进制模式下有效;设为1时,在文本模式下使用行缓冲;设为大于1的整数时,指定缓冲区大小。若未提供该参数,则采用默认策略,具体如下:
1)对于二进制文件模式,采用固定块内存缓冲方式,块大小由系统设备分配的磁盘块决定;若获取系统磁盘块大小失败,则使用内部常量io.DEFAULT_BUFFER_SIZE定义的大小。一般操作系统上,块大小为4096或8192字节。
2)对于交互文本文件(通过isatty()判断为True),采用行缓冲方式;其他文本文件则采用与二进制文件相同的缓冲方式。
参数encoding用于指定文件编码,仅适用于文本文件。若未指定编码方式,默认使用locale.getpreferredencoding()函数返回的编码。
参数errors用于指定编码和解码出错时的处理策略,该参数不能在二进制模式下使用。
1)当指定为'strict'时,编码出错将抛出ValueError异常。
2)当指定为'ignore'时,忽略编码错误。
3)当指定为'replace'时,使用特定字符(如'?')替换出错部分。
4)其他可选策略还包括surrogateescape、xmlcharrefreplace和backslashreplace。
参数newline用于控制文本模式下的行结束符,可设置为None、''、\n、\r或\r\n等。
1)在读取模式下,若newline为None,则启用通用换行符模式,即遇到\n、\r或\r\n均视为换行标识,并统一转换为\n作为文本输入的换行符;若设置为空字符串'',同样启用通用换行符模式,但不进行转换,输入何种字符即保持原样输出;若设置为其他特定字符,则将该字符视为换行符,并保持原样输入到文本中。
2)在写入模式下,若newline为None,则所有输出文本均使用\n作为换行符;若设置为''或\n,则不进行任何替换操作;若设置为其他字符,则在该字符后添加\n作为换行符。
以上内容为本文的全部介绍,希望能为各位的学习提供帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









