Python:scrapy 爬取40天天气预报

爬虫对象选择#

打开中国天气网站,例如我要爬取厦门近 40 天的天气情况,打开对应的网页。“weather40d”目录是近 40 天的天气,“101230201”是厦门城市的 id。

Copy Highlighter-hljs
http://www.weather.com.cn/weather40d/101230201.shtml


打开开发者工具,观察到每一天的天气数据还是比较复杂的,所以我们还是要找 API。

在 network 中观察,Fetch/XHG 中没有任何请求的交互,说明这个网页要么是静态的,要么是用 JavaScript 动态生成的。

随便找一个在页面中的字符串,例如以 11 月 7 号的天气“多云转小雨”为例,可以看到搜索出一个结果。

查看这个 JavaScript 文件,可以看到这里罗列了一系列的数据。

打开详细的数据,发现这个字典里面的数据可以和网页的数据对应,说明这个就是我们想要的 js 文件。

查看这个请求的请求头,得到这个 js 文件的 url。

但是访问这个 url,发现回显 403 错误。403 错误表示资源不可用,也就是服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的。

也就是说只有特定的地方发起请求才能获取这个资源,查看请求头,发现 “Referer” 字段的值为中国天气网站。Referer 字段用于告诉服务器该网页是从哪个页面链接过来的,因此很有可能我们想要的 js 文件只接受来源于该网站的请求。同时还有一个“User-Agent”字段也需要设置,User-Agent 字段会告诉网站服务器访问者是通过什么工具来请求的。

创建 scrapy 工程#

Scrapy 是适用于 Python 的一个快速、高层次的屏幕抓取和 web 抓取框架,用于抓取 web 站点并从页面中提取结构化的数据,提供了多种类型爬虫的基类。

和之前用 requests 库不同,要使用 Scrapy 框架需要创建一个 Scrapy 工程,可以在 cmd 使用命令创建。

Copy Highlighter-hljs
scrapy startproject 工程名

Scrapy 的项目的目录结构如下:

Copy Highlighter-hljs
scrapy.cfg myproject/ __init__.py items.py pipelines.py settings.py spiders/ __init__.py spider1.py spider2.py ...

接着可以进入目录下进行初始化,使用命令指示要爬取的 Url,Scrapy 会为之建立一个爬虫文件。

Copy Highlighter-hljs
cd 工程名 scrapy genspider 爬虫名 Url

例如我新建一个工程 weather,并且初始化一个爬虫文件 XMWeather 并指定 url 如下。

Copy Highlighter-hljs
scrapy startproject weather cd weather scrapy genspider XMWeather http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html

代码编写#

items.py#

Scrapy 提供 Item 类,实例化后的 Item 对象是种简单的容器,用于保存了爬取到得数据。其提供了类似于字典的 API 以及用于声明可用字段的简单语法,Item 使用简单的 class 定义语法以及 Field 对象来声明。
注意由于我们爬取的是包含 JSON 字符串的 JavaScript 文件,所以只需要将 JSON 字符串存起来即可,所以 Item 里面只有一个 content 字段。

Copy Highlighter-hljs
import scrapy class WeatherItem(scrapy.Item): content = scrapy.Field()

spiders/XMWeather.py#

Spider 类定义了如何爬取网站,包括了爬取的动作以及如何从网页的内容中提取结构化数据。当我们编写 Spider 类时需要在 spiders 文件夹下创建 py 文件,由于我们刚刚有初始化所以这里已经有一个 py 文件了。
Scrapy 爬取之后将返回一个 response 对象,parse() 是处理下载的 response 的默认方法,这个方法应该将数据处理后填充进一个实例化后的 Item 类对象中并返回。使用 response.body_as_unicode() 可以获得 response 对象的内容,由于我定义的 Item 只有一个字段,所以设置这个字段并返回即可。

Copy Highlighter-hljs
import scrapy from weather.items import WeatherItem class XmweatherSpider(scrapy.Spider): name = 'XMWeather' allowed_domains = ['d1.weather.com.cn'] start_urls = ['http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html'] def parse(self, response): #实例化 Item 对象 item = WeatherItem() item['content'] = response.body_as_unicode()[11:] return item

观察 Response 的内容,发现除了开头的 “var fc40 = [”这一串字符串,后面的内容都是以 json 的格式存在的。所以只需要把一开始的 “var fc40 = [”删掉,请求的内容就可以以 JSON 的格式解析。

pipelines.py#

当 Item 在 Spider中被收集之后,它将会被传递到 Item Pipeline,pipelines.py 中的组件将会按照一定的顺序执行对 Item 的处理。每个 item pipeline 组件是实现了简单方法的 Python 类,接收到 Item 后将执行一些行为进行处理,例如存储入文件当中。
此处我编写了 WeatherPipeline 类用于将 item 中的 content 字段解析为 JSON 对象,然后存储如 xls 文件中。

Copy Highlighter-hljs
from itemadapter import ItemAdapter import json import xlwt class WeatherPipeline: def process_item(self, item, spider): weathers = json.loads(item['content']) writebook = xlwt.Workbook() sheet = writebook.add_sheet('Sheet1') keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als'] for i in range(len(keys)): sheet.write(0, i, keys[i]) for i in range(len(weathers)): for j in range(len(keys)): sheet.write(i + 1, j, weathers[i][keys[j]]) writebook.save('weathers.xls')

settings.py#

Scrapy 的 settings 提供了定制 Scrapy 组件的方法,可以控制包括核心、插件、pipeline 及 spider 组件。设定为代码提供了提取以 key-value 映射的配置值的的全局命名空间,settings 同时也是选择当前激活的 Scrapy 项目的方法。
由于 url 有来源检测,所以我们要设置 DEFAULT_REQUEST_HEADERS 修改报文的请求头。ITEM_PIPELINES 则是指定了用来处理数据的 Pipeline,后面的值表示的是优先级。

Copy Highlighter-hljs
BOT_NAME = 'weather' SPIDER_MODULES = ['weather.spiders'] NEWSPIDER_MODULE = 'weather.spiders' ROBOTSTXT_OBEY = True DEFAULT_REQUEST_HEADERS = { "Referer":"http://www.weather.com.cn/", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" } ITEM_PIPELINES = { 'weather.pipelines.WeatherPipeline': 300 }

项目运行#

在项目目录下使用 scrapy crawl 命令可以运行该项目,也可以加上 nolog 使其不输出日志信息。

Copy Highlighter-hljs
scrapy crawl 爬虫名 scrapy crawl 爬虫名 --nolog

运行项目之后的效果如下:

Copy Highlighter-hljs
scrapy crawl XMWeather --nolog


参考资料#

Scrapy 0.24 文档

posted @   乌漆WhiteMoon  阅读(1291)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-11-17 sqli-labs 通关指南:Less 46 ~ 49
2019-11-17 C语言--数组
点击右上角即可分享
微信分享提示
CONTENTS