理解Scrapy框架各个组成的作用:五大组成,下载器,调度器,引擎,爬虫,管道。
引擎:它是整个Scrapy框架的核心,用来处理整个系统的数据流,触发各种事件。用于控制调度器,下载器,爬虫,管道。
爬虫:用户可以通过正则,xpath等语法从特定的网页中提取需要的信息,即实体(Item).。也可以提取出链接,让Scrapy继续抓取下一个页面。
实体管道:用于接收爬取到的数据,以便于进一步处理,比如可以存入数据库,本地文件等进行持久化存储。
下载器:用于高速地下载网络上的资源。它是建立在twisted这个高效的异步模型上。
调度器:其就是一个url的优先队列,由它来决定下一个要抓取的网址是什么,同时去掉重复的网址。可以根据需求定制调度器。
Scrapy爬取链家网一个页面数据并且保存到本地文件:
需要爬取的链接:北京二手房房源_北京二手房出售|买卖|交易信息(北京链家) (lianjia.com)
一,明确需要爬取的数据
创建一个Item(实体)类,这里我们要爬取的数据有
标题,位置,房屋信息,总价和均价,对此我们可以在items.py文件中定义一个
Lianjia类,参考代码如下:
class lianjia(scrapy.Item):
title = scrapy.Field()
positionPre = scrapy.Field()
positionAft = scrapy.Field()
houseInfo = scrapy.Field()
totalPrice = scrapy.Field()
unitPrice = scrapy.Field()
二,明确完数据后,我们就可以开始进行响应解析了,打开spiders文件,
找到我们的爬虫文件(爬虫名.py),首先导入我们之前在items.py定义的ITEM(实体类):
参考代码如:from ..items import Lianjia
然后开始解析,由于xpath解析比较简单就不在赘述,拿到我们需要的数据后,实例化ITEM(实体类),
将数据保存至这个ITEM(实体类中),然后yiled返回这个item对象。 参考代码如下:
def parse(self, response):
li_list = response.xpath('.//ul[@class="sellListContent"]/li')
for li in li_list:
title = li.xpath('.//div[1]/div[1]/a/text()').extract_first()
positionPre = li.xpath('.//div[@class="positionInfo"]/a[1]/text()').extract_first()
positionAft = li.xpath('.//div[@class="positionInfo"]/a[2]/text()').extract_first()
houseInfo = li.xpath('.//div[@class="houseInfo"]/text()').extract_first()
totalPrice = li.xpath('.//div[@class="totalPrice totalPrice2"]/span/text()').extract_first()
unitPrice = li.xpath('.//div[@class="unitPrice"]/span/text()').extract_first()
item = Lianjia()
item['title'] = title
item['positionPre'] = positionPre
item['positionAft'] = positionAft
item['houseInfo'] = houseInfo
item['totalPrice'] = totalPrice
item['unitPrice'] = unitPrice
yield item
三,爬取完数据后,再进行数据的持久化存储,这里我们只保存到本地txt文件
在pipelines.py文件里定义一个管道类,对yield返回的item我们进行保存到txt文件的操作,参考代码如下:
class FirstspiderPipeline:
fp = None
def open_spider(self, spider):
print("爬虫开始")
self.fp = open('./链家二手房数据.txt', 'w', encoding='utf-8')
def process_item(self, item, spider):
self.fp.write(
f'标题:{item["title"]}\n
位置:{item["positionPre"]}
{item["positionAft"]}\n
房屋信息:{item["houseInfo"]}\n
总价:{item["totalPrice"]}万\n
均价:{item["unitPrice"]}\n\n')
return item
def close_spider(self, spider):
print("爬虫结束")
self.fp.close()
四,将这些都执行后,再设置setting.py文件,
设置USER_AGENT:USER_AGENT = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
设置robot协议将TRUE改成False:ROBOTSTXT_OBEY = False
设置管道:
ITEM_PIPELINES = {
'firstSpider.pipelines.FirstspiderPipeline': 300,
}
最后在终端中输入:scrapy crawl lianjia运行即可。
可以看到生成了个文件
在这个例子,首先由爬虫将start_urls起始网址(需要爬取的域名)提交给引擎,让引擎将这个网址交给调度器,
调度器将其入队后出队优先爬取的网址(这里我们没做翻页只有一个域名)交给引擎,
引擎将其交给下载器高速地下载网络资源得到一个响应再将这个响应交给引擎,引擎将这个响应提交给爬虫
由响应处理函数对这个响应进行解析获取到需要的信息,将这个信息保存到Item实体类中,然后yield返回这个item将其
交给引擎,引擎将其给管道,由管道进行持久化存储。
终端中的命令:
创建一个Scrapy框架项目:在终端中输入:scrapy startproject 项目名
创建一个爬虫:在终端中输入:cd 项目名,进入项目后输入:scrapy genspider 爬虫名 域名(这个域名就是要爬取的起始地址)
创建一个CrawlSpider爬虫:在终端中输入:cd 项目名,进入项目后输入:scrapy genspider -t crawl 爬虫名 域名
运行爬虫:在终端中输入:cd 项目名,进入项目后输入:scrapy crawl 爬虫名
scrapy shell脚本:在终端中输入:scrapy shell 域名,进入后可以进行各种调试或xpath获取数据等