好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

实操 | 从0到1教你用Python来爬取整站天气网

Scrapy

Scrapy是Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。

一、安装scrapy

安装Twisted

Twisted:为 Python 提供的基于事件驱动的网络引擎包。

在下面网址安装Twisted

url:https://HdhCmsTestlfd.uci.edu/~gohlke/pythonlibs/

安装scrapy

cmd输入 pip install scrapy

安装完毕,cmd里输入scrapy出现安装成功。

二、了解scrapy

Scrapy的组件

引擎,用来处理整个系统的数据流处理,触发事务。

调度器,用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。

下载器,用于下载网页内容,并将网页内容返回给蜘蛛。

蜘蛛,蜘蛛是主要干活的,用它来制订特定域名或网页的解析规则。

项目管道,负责处理有蜘蛛从网页中抽取的项目,主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

下载器中间件,位于Scrapy引擎和下载器之间的钩子框架,主要是处理Scrapy引擎与下载器之间的请求及响应。

蜘蛛中间件,介于Scrapy引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛的响应输入和请求输出。

调度中间件,介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。

其处理流程为:

引擎打开一个域名时,蜘蛛处理这个域名,并让蜘蛛获取第一个爬取的URL。

引擎从蜘蛛那获取第一个需要爬取的URL,然后作为请求在调度中进行调度。

引擎从调度那获取接下来进行爬取的页面。

调度将下一个爬取的URL返回给引擎,引擎将他们通过下载中间件发送到下载器。

当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎。

引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。

蜘蛛处理响应并返回爬取到的项目,然后给引擎发送新的请求。

引擎将抓取到的项目项目管道,并向调度发送请求。

系统重复第二部后面的操作,直到调度中没有请求。

三、项目分析

爬取天气网城市的信息url : https://HdhCmsTestaqistudy.cn/historydata/

爬取主要的信息: 热门城市每一天的空气质量信息

点击月份还有爬取每天的空气质量信息

四、新建项目

新建文件夹命令为天气网爬虫

cd到根目录,打开cmd,运行 scrapy startproject weather_spider

创建spider

cd到根目录,运行 scrapy genspider weather HdhCmsTestaqistudy.cn/historydata

这里的weather是spider的名字

创建的路径如下:

五、代码编写

对于scrapy,第一步,必须编写item.py,明确爬取的对象

item.py

?scrapy

????
????
????
????city?=?scrapy.Field()
????date?=?scrapy.Field()
????aqi?=?scrapy.Field()
????level?=?scrapy.Field()
????pm25?=?scrapy.Field()
????pm10?=?scrapy.Field()
????so2?=?scrapy.Field()
????co?=?scrapy.Field()
????no2?=?scrapy.Field()
????o3_8h?=?scrapy.Field()

对于爬取必须伪装好UA,在setting.py中定义 MY_USER_AGENT 来存放UA,注意在settings中命名必须大写

settings.py

MY_USER_AGENT?=?[
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
????,
]

在定义好UA后,在middlewares.py中创建 RandomUserAgentMiddleware 类

middlewares.py

?random

????
????????self.user_agents?=?user_agents

????@classmethod
????
????????
????????s?=?cls(user_agents=crawler.settings.get())
?????????s

????
????????agent?=?random.choice(self.user_agents)
????????request.headers[]?=?agent

注意要在settings.py中激活,必须是900,来去掉scrapy本身的UA

setting.py

DOWNLOADER_MIDDLEWARES?=?{
???:,
}

开始编写最重要的spider.py,推荐使用scrapy.shell来一步一步调试

先拿到所有的城市

在scrapy中xpath方法和lxml中的xpath语法一样

我们可以看出url中缺少前面的部分,follow方法可以自动拼接url,通过meta方法来传递需要保存的city名字,通过callback方法来调度将下一个爬取的URL

weather.py

????city_urls?=?response.xpath().extract()[:]
????city_names?=?response.xpath().extract()[:]
????self.logger.info(.format(city_names[]))
?????city_url,?city_name??zip(city_urls,?city_names):
????????
?????????response.follow(url=city_url,?meta={:?city_name},?callback=self.parse_month)

这时就是定义parse_month函数,首先分析月份的详情页,拿到月份的url

还是在scrapy.shell 中一步一步调试

通过follow方法拼接url,meta来传递city_name要保存的城市名字,selenium:True先不管然后通过callback方法来调度将下一个爬取的URL,即就是天的爬取详细页

weather.py

????
????city_name?=?response.meta[]
????self.logger.info(.format(city_name[]))
????
????month_urls?=?response.xpath().extract()[:]
?????month_url??month_urls:
?????????response.follow(url=month_url,?meta={:?city_name,?:?},?callback=self.parse_day_data)

现在将日的详细页的信息通过xpah来取出

发现竟然为空

同时发现了源代码没有该信息

说明了是通过js生成的数据,scrapy只能爬静态的信息,所以引出的scrapy对接selenium的知识点,所以上面meta传递的参数就是告诉scrapy使用selenium来爬取。复写 WeatherSpiderDownloaderMiddleware 下载中间件中的process_request函数方法middlewares.py

?time
?scrapy
?selenium??webdriver
?selenium.webdriver.chrome.options??Options

????
?????????request.meta.get():
????????????
????????????chrome_options?=?Options()
????????????
????????????chrome_options.add_argument()
????????????driver?=?webdriver.Chrome(chrome_options=chrome_options)
????????????
????????????driver.get(request.url)
????????????time.sleep()??
????????????html?=?driver.page_source
????????????driver.quit()
?????????????scrapy.http.HtmlResponse(url=request.url,?body=html,?encoding=,?request=request)

激活WeatherSpiderDownloaderMiddleware

DOWNLOADER_MIDDLEWARES?=?{
???:?,
???:,
}

最后编写weather.py中的剩下代码

?..items??WeatherSpiderItem

????

????node_list?=?response.xpath()
????
????node_list.pop()
????print(response.body)
????print()
????print(node_list)
?????node??node_list:
????????item?=?WeatherSpiderItem
????????item[]?=?response.meta[]
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
????????item[]?=?node.xpath().extract_first()
?????????item

六、运行项目

一定要注意项目的根目录执行命令,可以通过 scrapy list 查看是否存在项目

scrapy保存信息的最简单的方法主要有四种,-o 输出指定格式的文件,命令如下:默认json

scrapy crawl weather -o spider.json

json lines格式,默认为Unicode编码

scrapy crawl weather -o spider..jl

csv 逗号表达式,可用Excel打开

scrapy crawl weather -o spider..csv

xml格式

scrapy crawl weather -o spider..xml

但是保存的编码不对,必须在settings中加入 FEED_EXPORT_ENCODING = 'utf-8'

七、入库操作

这里入的库是Mongodb,在settings.py中配置

MONGO_URI=?
MONGO_DB=

对于入门主要处理的是pipelines中

pipelines.py

?pymongo


????
????????self.mongo_uri=mongo_uri
????????self.mongo_db=mongo_db

????@classmethod
????
?????????cls(
????????????mongo_uri=crawler.settings.get(),
????????????mongo_db=crawler.settings.get()
????????)

??????
????????self.client?=?pymongo.MongoClient(self.mongo_uri)
????????self.db?=?self.client[self.mongo_db]

????
????????name?=?item.__class__.__name__
????????self.db[name].insert(dict(item))??
?????????item

??????
????????self.client.close()

在settings中激活pipelines

ITEM_PIPELINES?=?{
???:?,
}

效果如下

八、结语

我们本次通过爬取天气网站的来作为学习? Scrapy ?的,这里展示的关于? Scrapy ?大部分的知识点。如果改写列表,就可以爬取北京所有的天气信息,当然还可以爬取全部城市的天气信息,即这个天气网的全部内容基本都爬取。

查看更多关于实操 | 从0到1教你用Python来爬取整站天气网的详细内容...

  阅读:24次