好得很程序员自学网

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

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

Scrapy

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

一、安装scrapy

安装Twisted

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

在下面网址安装Twisted

url:https://www.lfd.uci.edu/~gohlke/pythonlibs/

安装scrapy

cmd输入 pip install scrapy

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

二、了解scrapy

Scrapy的组件

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

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

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

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

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

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

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

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

其处理流程为:

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

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

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

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

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

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

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

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

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

三、项目分析

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

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

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

四、新建项目

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

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

创建spider

cd到根目录,运行 scrapy genspider weather www.aqistudy.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来爬取整站天气网的详细内容...

  阅读:22次