scrapy爬虫并保存数据库

443次阅读
没有评论

上一篇文章中简单地讲述用scrapy进行简单爬虫流程

https://blog.csdn.net/reset2021/article/details/124449231?spm=1001.2014.3001.5502

这里在上篇文章的基础上讲述怎样用scrapy实现爬虫,并且保存到数据库中。

1、scrapy框架

      scrapy框架如下图所示:

scrapy爬虫并保存数据库

 其中,包含两个中间件:下载器中间件(Downloader Middleware)和爬虫中间件(Spider Middleware)。使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。

1) downloader Middleware

  • 下载器中间件是介于Scrapy的request/response处理的钩子框架,是用于全局修改Scrapy request和response的一个轻量、底层的系统

  • 用于更换代理IP,更换Cookies,更换User-Agent,自动重试。

  • Scrapy其实自带了UA中间件(UserAgentMiddleware)、代理中间件(HttpProxyMiddleware)和重试中间件(RetryMiddleware)

  • 从原则上说,要自己开发这3个中间件,需要先禁用Scrapy里面自带的这3个中间件。要禁用Scrapy的中间件,需要在settings.py里面将这个中间件的顺序设为None

process_request(request, spider)

Request被Scrapy引擎调度给Downloader之前,process_request()方法就会被调用,也就是在Request从队列里调度出来到Downloader下载执行之前,我们都可以用process_request()方法对Request进行处理。

方法的返回值必须为None、Response对象、Request对象之一,或者抛出IgnoreRequest异常。

process_response(request, response, spider)

Downloader执行Request下载之后,会得到对应的Response。Scrapy引擎便会将Response发送给Spider进行解析。

在发送之前,我们都可以用process_response()方法来对Response进行处理。方法的返回值必须为Request对象、Response对象之一,或者抛出IgnoreRequest异常

process_exception(request, exception, spider)

当Downloader或process_request()方法抛出异常时,例如抛出IgnoreRequest异常,process_exception()方法就会被调用。

方法的返回值必须为None、Response对象、Request对象之一

2) spider Middleware

当Downloader生成Response之后,Response会被发送给Spider,在发送给Spider之前,Response会首先经过Spider Middleware处理

当Spider处理生成Item和Request之后,Item和Request还会经过Spider Middleware的处理

spider Middleware有如下三个作用:

在Downloader生成的Response发送给Spider之前,也就是在Response发送给Spider之前对Response进行处理。 在Spider生成的Request发送给Scheduler之前,也就是在Request发送给Scheduler之前对Request进行处理。 在Spider生成的Item发送给Item Pipeline之前,也就是在Item发送给Item Pipeline之前对Item进行处理

process_spider_input(response, spider)

当Response被Spider Middleware处理时,process_spider_input()方法被调用

process_spider_output(response, result, spider)

当Spider处理Response返回结果时,process_spider_output()方法被调用

process_spider_exception(response, exception, spider)

当Spider或Spider Middleware的process_spider_input()方法抛出异常时,process_spider_exception()方法被调用

process_start_requests(start_requests, spider)

process_start_requests()方法以Spider启动的Request为参数被调用,执行的过程类似于process_spider_output(),只不过它没有相关联的Response,并且必须返回Request

3)在Middleware中增加打印

class MiddleproDownloaderMiddleware:

def process_request(self, request, spider): print('process_request()') return None

def process_response(self, request, response, spider): print('process_response') return response

def process_exception(self, request, exception, spider):

print('process_exception')

打印如下所示:

process_request() process_request() process_response process_request() <200 https://www.search.jd.com> process_response <200 https://www.search.jd.com>

2、京东爬虫实例

从京东爬取关键词为"小米手机"的数据并保存到数据库中

1)配置关键词与数据库(修改settings.py)

KEYWORDS = ['小米手机']

MONGO_URI = '0.0.0.0'

MONGO_DB = 'xiaomi'

2)修改url:

将初始url设置为"https://search.jd.com/Search?keyword="

class JingDongSpider(Spider): name = 'jingdong' allowed_domains = ['search.jd.com'] base_url = 'https://search.jd.com/Search?keyword='

3)修改url的完整配置(拼接完整的url)

def start_requests(self): for keyword in self.settings.get('KEYWORDS'): for page in range(1, self.settings.get('MAX_PAGE') + 1): url = self.base_url + '{}&enc=utf-8&wq={}'.format(quote(keyword),quote(keyword)) yield Request(url=url, callback=self.parse, meta={'page': page}, dont_filter=True)

4)修改下载中间件,处理url的下载

def process_request(self, request, spider):

self.logger.debug('PhantomJS is Starting') page = request.meta.get('page', 1) try: self.browser.get(request.url) # 页面下拉 self.browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') time.sleep(5) if page > 1: input = self.wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, '#J_bottomPage > span.p-skip > input'))) submit = self.wait.until( EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_bottomPage > span.p-skip > a'))) input.clear() input.send_keys(page) submit.click() # 页面下拉 self.browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') self.wait.until( EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#J_bottomPage > span.p-num > a.curr'), str(page))) self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#J_goodsList > ul > li.gl-item'))) return HtmlResponse(url=request.url, body=self.browser.page_source, request=request, encoding='utf-8', status=200) except TimeoutException: return HtmlResponse(url=request.url, status=500, request=request)

5)修改parse,处理网页数据

def parse(self, response)

3、执行爬虫命令

scrapy crawl jingdong

查询数据爬取结果

{ "_id" : ObjectId("627616a2bfe03a4fdc0667a4"), "price" : "1549.00", "title" : "小米Redmi红米 Note11E Pro 5G 智能新品手机 夜海琉璃 6GB+128GB【官方标配】", "shop" : "疆界互联旗舰店", "image" : "//img13.360buyimg.com/n7/jfs/t1/115086/2/24178/122964/62305590E4c84d946/5ecdcf6eaa7ef3ae.jpg", "deal" : "7" } { "_id" : ObjectId("627616a9bfe03a4fdc0667a5"), "price" : "599.00", "title" : "Redmi 9A 5000mAh大电量 1300万AI相机 八核处理器 人脸解锁 4GB+64GB 砂石黑 智能手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "//img12.360buyimg.com/n7/jfs/t1/20435/30/15987/178578/626bc698E4016a8ae/8ecd4fe7c6af21b5.jpg", "deal" : "300万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667a6"), "price" : "1349.00", "title" : "京品手机\t\nRedmi Note 9 Pro 5G 一亿像素 骁龙750G 33W快充 120Hz刷新率 湖光秋色 8GB+256GB 智能手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "//img12.360buyimg.com/n7/jfs/t1/142405/30/15860/47809/5fbe0736E3284d091/0b92f82917a9c400.jpg", "deal" : "100万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667a7"), "price" : "2299.00", "title" : "小米 Civi 1S 骁龙778G Plus 3200万双柔光自拍 120Hz曲面原色屏 4500mAh大电量 5G手机 8G+128GB 奇迹阳光", "shop" : "小米京东自营旗舰店", "image" : "//img11.360buyimg.com/n7/jfs/t1/91036/40/28744/92184/6273ae05E72c36d59/aa1ee50c05d1f330.jpg", "deal" : "2000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667a8"), "price" : "2999.00", "title" : "小米12X 5G手机 骁龙870 黄金手感 6.28英寸视感屏 120Hz高刷 黑色【67W充电器套装】 8GB+128GB", "shop" : "小米手机官方旗舰店", "image" : "", "deal" : "500+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667a9"), "price" : "2199.00", "title" : "Redmi Note 11 Pro+ 5G 三星AMOLED高刷屏 1亿像素 120W快充 VC液冷散热 8GB+256GB 神秘黑境 手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "50万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667aa"), "price" : "1899.00", "title" : "小米11青春版 骁龙780G处理器 AMOLED柔性直屏 8GB+128GB 冰峰黑提 5G时尚手机", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "20万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667ab"), "price" : "1999.00", "title" : "小米 红米Note11 5G 新品Redmi智能手机 6G+128G 神秘黑境 官方标配【晒单有礼】", "shop" : "疆界互联旗舰店", "image" : "", "deal" : "5000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667ac"), "price" : "649.00", "title" : "Redmi 10A 5000mAh大电量 1300万AI相机 八核处理器 指纹解锁 4GB+64GB 暗影黑 智能手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "2万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667ad"), "price" : "2799.00", "title" : "Redmi K50 天玑8100 2K柔性直屏 OIS光学防抖 67W快充 5500mAh大电量 墨羽 12GB+256GB 5G智能手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "10万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667ae"), "price" : "1299.00", "title" : "Redmi Note 11 5G 天玑810 33W Pro快充 5000mAh大电池 6GB +128GB 神秘黑境 智能手机 小米 红米", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "20万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667af"), "price" : "1999.00", "title" : "Redmi K40S 骁龙870 三星E4 AMOLED 120Hz直屏 OIS光学防抖 67W快充 亮黑 8GB+128GB 5G智能手机 小米红米", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "5万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b0"), "price" : "3999.00", "title" : "小米12 骁龙8 Gen1 黄金手感 6.28英寸视感屏 120Hz高刷 5000万疾速影像 67W快充 8GB+256GB 黑色 5G手机", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "10万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b1"), "price" : "5999.00", "title" : "小米11 Ultra 至尊 5G", "shop" : "小米京东自营旗舰店", "image" : "", "deal" : "10万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b2"), "price" : "1098.00", "title" : "小米 Redmi 红米Note9 5G手机 云墨灰 全网通(8G+128G)", "shop" : "掌视界数码旗舰店", "image" : "", "deal" : "1万+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b3"), "price" : "1269.00", "title" : "小米 红米note11 新品5G手机 神秘黑镜 6+128GB 全网通", "shop" : "炜东电商旗舰店", "image" : "", "deal" : "5000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b4"), "price" : "1099.00", "title" : "小米 红米Note11 4G 新品Redmi智能手机 6G+128G 梦幻晴空 【官方标配】", "shop" : "酷族数码旗舰店", "image" : "", "deal" : "5000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b5"), "price" : "1499.00", "title" : "小米 Redmi 红米Note10Pro 游戏智能5G手机 新品 星纱 8GB+128GB 官方标配", "shop" : "茄子手机旗舰店", "image" : "", "deal" : "5000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b6"), "price" : "1799.00", "title" : "小米 Redmi 红米 Note11 Pro 游戏智能5G手机 新品 8GB+128GB 迷雾森林 官方标配【碎屏险+晒单有礼】", "shop" : "茄子手机旗舰店", "image" : "", "deal" : "5000+" } { "_id" : ObjectId("627616a9bfe03a4fdc0667b7"), "price" : "2999.00", "title" : "【12期免息】小米 红米K50 Pro 5G Redmi新品手机 墨羽【官方标配】 8G+128G【碎屏险+晒单30红包】", "shop" : "疆界互联旗舰店", "image" : "", "deal" : "1000+" }

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:Python教程2022-10-25发表,共计8104字。
新手QQ群:570568346,欢迎进群讨论 Python51学习