Scrapy
请不要大量并且长时间爬取同一网站,这样会给被访问的网站服务器带来巨大压力
- 概述:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。
这张图很清晰的解释Scrapy的运转:- 引擎(Scrapy Engine):框架核心,负责控制系统中的数据流。
- 调度器(Scheduler):从引擎接受request,然后入队,在引擎请求时返回给引擎,如果没有得到request将关闭网站。
- 下载器(Downloader):从引擎得到request,将所需的页面下载下来生成一个response,并发送给引擎。
- 爬虫文件(Spiders):从引擎得到response,从其中将我们所需要的东西(item)爬取下来,并和新的request发送给引擎。
- 管道(Item Pipeline):从引擎得到item,将数据进行处理,例如清洗、验证、持续化等。
- 下载中间件(Downloader Middlewares):处理Downloader的输入(request)和输出(response)。
- 爬虫中间件(Spider Middlewares):处理Spiders的输入(request)和输出(response)。
- 目录结构
scrapy/
scrapy/
spiders/
__init__.py
spider.py # 爬虫文件
……
__init__.py
items.py # 保存爬取到的数据的容器以及数据模板
middlewares.py # 设置中间件的一些属性
pipelines.py # 数据处理行为
settings.py # 和爬虫相关的设置文件
scrapy.cfg # 基础的配置信息
-
下面是我写的一个关于爬取某个地区近10年的天气情况的项目
- 首先建议先用anaconda prompt进行scrapy shell调试将网页内容提取出来,推荐使用BeautifulSoup(bs4)或者xpath
- 调试完成后,就可以写items.py文件(将网页的哪些内容保存),再将spider.py文件根据你的调试写出(由于spider.py太长,我就不展示了,此处有代码链接)
# items.py import scrapy class TianqiItem(scrapy.Item): day = scrapy.Field() # 日期 weatherm = scrapy.Field() # 白天天气 weathern = scrapy.Field() # 晚上天气 temm = scrapy.Field() # 白天温度 temn = scrapy.Field() # 晚上温度 windm = scrapy.Field() # 白天风向 windn = scrapy.Field() # 晚上风向
- 然后根据items.py文件,写出pipeline.py文件(选择保存方式)
# pipeline.py(这里采用的是mysql数据库的异步存储) import pymysql from twisted.enterprise import adbapi class TianqiPipeline(object): def __init__(self, dbpool): self.dbpool = dbpool @classmethod def from_settings(cls, settings): # 函数名不可更改 dbparms = dict( host=settings['MYSQL_HOST'], db=settings['MYSQL_DBNAME'], user=settings['MYSQL_USER'], passwd=settings['MYSQL_PASSWORD'], charset=settings['MYSQL_CHARSET'], use_unicode=True, cursorclass=pymysql.cursors.DictCursor # 游标设置为字典型 ) # 建立连接池,**表示参数对 dbpool = adbapi.ConnectionPool("pymysql", **dbparms) return cls(dbpool=dbpool) def process_item(self, item, spider): result = self.dbpool.runInteraction(self.insert, item) result.addErrback(self.error) # 定义出现错误的处理方法 def error(self, reason): print(reason) # 定义插入方法 def insert(self, cursor, item): sql = "insert weinan values(%s, %s, %s, %s, %s, %s, %s)" cursor.execute(sql, (item['day'], item['weatherm'], item['weathern'], item['temm'], item['temn'], item['windm'], item['windn']))
- 最后将settings.py和middlewares.py文件补充完善,一般middlewares.py是不需要完善的,但随机更换用户代理与IP可以写到此文件当中,如果你要更换的话,请将settings中的DOWNLOADER_MIDDLEWARES的参数解除注释
# settings 需要添加的 # 数据库的连接需要的参数 MYSQL_HOST = 'localhost' MYSQL_DBNAME = 'weather' MYSQL_USER = 'root' MYSQL_PASSWORD = 'haha' MYSQL_CHARSET = 'utf8' # 这里没有写错就是utf8没有- # 需要解除注释 ITEM_PIPELINES = { 'tianqi.pipelines.TianqiPipeline': 300, }
- 最后建议大家在和scrapy.cfg文件同级处建立一个begin.py用来启动整个项目
from scrapy import cmdline cmdline.execute('scrapy crawl tianqispider'.split())