Scrapy
Scrapy是Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。
一、安装scrapy
安装TwistedTwisted:为 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来爬取整站天气网的详细内容...