【爬虫】第七部分 scrapy

news/2024/11/20 0:32:59/

【爬虫】第七部分 scrapy


文章目录

  • 【爬虫】第七部分 scrapy
  • 7. scrapy
    • 7.1 基本使用
    • 7.2 项目的文件结构
    • 7.3 response的方法和属性
    • 7.4 小案例
    • 7.5 scrapy 工作原理
    • 7.6 管道的使用
    • 7.7 多管道下载
    • 7.8 下载分页类型和get请求的使用
    • 7.9 下载多层级类型
    • 7.10 post请求的使用
  • 总结


7. scrapy

7.1 基本使用

  1. pip install scrapy 安装

  2. 在终端运行以下代码: scrapy startproject 项目名字 创建爬虫项目(名字不要中文)

  3. cd 进入到 spiders,再运行下面创建爬虫文件的指令

在这里插入图片描述

scrapy genspider 爬虫文件名 要爬取的网页 创建爬虫文件(名字不要中文)

ex: scrapy genspider xxx www.xxx.com

这个时候我们就会看到spiders下面生成了xxx.py文件
在这里插入图片描述

  1. 运行爬虫文件 scrapy crawl 爬虫文件名字 ,注意运行之前到settings中将robot协议改了,才可以爬取

在这里插入图片描述


7.2 项目的文件结构

scrapy 项目的文件结构- 项目名- 项目名- spidersinit自定义的爬虫文件- init- items  定义数据结构的地方- middleware 中间件  代理- pipelines  管道 用来处理下载下来的数据- settings 配置文件 robots协议 us定义等

7.3 response的方法和属性

extract(): 这个方法返回的是一个数组list里面包含了多个string,如果只有一个string,则返回[‘ABC’]这样的形式。

extract_first():这个方法返回的是一个string字符串是list数组里面的第一个字符串

import scrapyclass BaiduSpider(scrapy.Spider):# 爬虫文件的名字,用于运行爬虫的时候使用name = 'baidx'# 允许访问的域名allowed_domains = ['www.baidx.com']# 起始的url地址,指的是第一次要访问的域名# 这里需要注意一下,一般情况下将start_urls中 / 给去掉,不然容易出现一些问题start_urls = ['http://www.baidx.com']# 该方法中的response相当于 response = requests.get()def parse(self, response):res1 = response.text  # 拿到的是字符串,网页源码res2 = response.body  # 拿到的是二进制数据print("===========================================================")# 可以直接使用xpath的方法content = response.xpath('//input[@id="su"]/@value')# 使用extract()方法进行提取print(content.extract())

7.4 小案例

爬取汽车信息

import scrapyclass CarSpider(scrapy.Spider):name = 'car'allowed_domains = ['https://xxx.autohome.com.cn/price/brand-15.html']start_urls = ['https://xxx.autohome.com.cn/price/brand-15.html']def parse(self, response):print("===========================")name_list = response.xpath('//div[@class="main-title"]/a/text()')price_list = response.xpath('//div[@class="main-lever-right"]/div/span/span/text()')for i in range(len(name_list)):res = name_list[i].extract() + '--->  ' + price_list[i].extract()print(res)

7.5 scrapy 工作原理

在这里插入图片描述

根据上述的流程图,绘制下图:

在这里插入图片描述

  1. 首先将spiders向引擎提供url
  2. 引擎将要爬取的url给调度器
  3. 调度器会将url生成请求对象放入到指定的队列中,队列中出队一个请求给引擎
  4. 引擎将请求件给下载器进行处理
  5. 下载器发送请求获取互联网数据
  6. 下载回来
  7. 下载器将数据返回给引擎
  8. 引擎将数据交给spiders,通过xpath解析数据
  9. 解析后的 数据 或者 url 交给引擎
  10. 引擎进行判断,如果是url则交给调度器,进行上述操作,如果是数据就交给管道保存下来

7.6 管道的使用

  1. 创建项目 : scrapy startproject dangdang

  2. 进入到spiders去创建爬虫文件 : scrapy genspider dang_data https://book.dangdang.com/01.03.htm?ref=book-01-A

  3. 编写创建出来的爬虫文件

    import scrapy
    # 导入定义数据结构
    from dangdang.items import DangdangItemclass DangDataSpider(scrapy.Spider):name = 'dang_data'allowed_domains = ['https://book.dangdang.com/01.03.htm?ref=book-01-A']start_urls = ['https://book.dangdang.com/01.03.htm?ref=book-01-A']def parse(self, response):# src   //ul[@class="list_aa"]//li[@type="rollitem"]//li/a/img/@src# bookname //ul[@class="list_aa"]//li[@type="rollitem"]//li/p[@class="name"]/a/text()# author  //ul[@class="list_aa"]//li[@type="rollitem"]//li/p[@class="author"]/text()base = response.xpath('//ul[@class="list_aa"]//li[@type="rollitem"]//li')# 只要是selector对象就可以继续调用xpathfor item in base:# 在这里需要注意加上 .  ,表示当前src = item.xpath('./a/img/@src').extract_first()bookname = item.xpath('./p[@class="name"]/a/text()').extract_first()author = item.xpath('./p[@class="author"]/text()').extract_first()# book实际上就是通过items整理好的对象,将该对象交给pipelines下载book = DangdangItem(src=src, bookname=bookname, author=author)# 使用yield 把对象交给pipelinesyield book
    
  4. 在items文件中定义数据结构

    import scrapyclass DangdangItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 在这里需要去定义你要下载的数据有哪些# 图片src = scrapy.Field()# 书名bookname = scrapy.Field()# 作者author = scrapy.Field()
    
  5. settings去开启管道

在这里插入图片描述

  1. 在pipelines文件中编写

    # 在使用管道前,需要去settings下开启管道
    class DangdangPipeline:# 这是一个在爬虫文件开始之前就执行的一个方法def open_spider(self, spider):self.f = open('book_msg.json', 'w', encoding='utf-8')def process_item(self, item, spider):# 这里的item就是yield返回过来的对象# write方法必须接受一个字符串而不能是其他的对象,需要强转self.f.write(str(item))# 注意一定要返回return item# 在爬虫文件执行完之后执行的一个方法:def close_spider(self, spider):self.f.close()

7.7 多管道下载

  1. 在pipelines原先的基础上模仿写

    # 在使用管道前,需要去settings下开启管道
    class DangdangPipeline:# 这是一个在爬虫文件开始之前就执行的一个方法def open_spider(self, spider):self.f = open('book_msg.json', 'w', encoding='utf-8')def process_item(self, item, spider):# 这里的item就是yield返回过来的对象# write方法必须接受一个字符串而不能是其他的对象,需要强转self.f.write(str(item))return item# 在爬虫文件执行完之后执行的一个方法:def close_spider(self, spider):self.f.close()import urllib.request# 开启多管道下载
    class DangdangDownload:def process_item(self, item, spider):url = 'https:' + item.get('src')filename = './books/' + item.get('bookname') + '.png'urllib.request.urlretrieve(url=url, filename=filename)return item
  2. 到settings文件中去添加新的管道,一样模仿这写

    # 开启管道,管道是有优先级的,优先级的范围是1-1000,值越小优先级越高
    ITEM_PIPELINES = {'dangdang.pipelines.DangdangPipeline': 300,# 开启多管道'dangdang.pipelines.DangdangDownload': 301
    }
    

7.8 下载分页类型和get请求的使用

创建出来的爬虫文件

import scrapy
import json
from pptmodel.items import PptmodelItemclass PptDemoSpider(scrapy.Spider):name = 'ppt_demo'# 对于下载分页这种类型,allowed_domains需要写成域名allowed_domains = ['theuser.zhuisoft.com']start_urls = ['http://theuser.zhuisoft.com/template/ajax_web/data_list?class=&type_id=0&order_by=0&title=&format=&page=0&num=40']def parse(self, response):res = response.textdata = json.loads(res).get('data')for item in data:title = item.get('title')img = item.get('cover_img')ppt = PptmodelItem(title=title, img=img)yield ppt# 下载3页for i in range(1, 3):url = f'http://theuser.zhuisoft.com/template/ajax_web/data_list?class=&type_id=0&order_by=0&title=&format=&page={i}&num=40'# scrapy.Request 就是scrapy的get请求,注意这里调用函数不能写括号yield scrapy.Request(url=url, callback=self.parse)

7.9 下载多层级类型

创建出来的爬虫文件

import scrapy
from movie_demo.items import MovieDemoItemclass MvSpider(scrapy.Spider):name = 'mv'allowed_domains = ['0dytt.com']start_urls = ['https://0dytt.com/frim/1.html']"""案例描述: 1. 需要在首页拿到电影名和跳转的链接2. 请求跳转的链接,xpath解析,拿到电影海报"""def parse(self, response):# href  //div[@class="hy-video-list"]//li/a/@href# title //div[@class="hy-video-list"]//li/a/@titlebase = response.xpath('//div[@class="hy-video-list"]//li/a')for i in base:href = 'https://0dytt.com' + i.xpath('./@href').extract_first()film_name = i.xpath('./@title').extract_first()# 这个时候去请求拿到的新链接# 在这里使用meta参数用来将电影名传入parse_pictureyield scrapy.Request(url=href, callback=self.parse_picture, meta={"film_name": film_name})# 因为页面结构的不同不能像上一个案例那样调用自己,所以需要创建一个新的函数def parse_picture(self, response):all_actor = ''style = response.xpath('//div[@class="hy-video-details clearfix"]//a/@style').extract_first()lead_actor = response.xpath('//div[@class="hy-video-details clearfix"]//ul/li[1]//a/text()').extract()for actor in lead_actor:all_actor = all_actor + actorfilm_name = response.meta['film_name']start = style.find('(')end = style.find(')')src = 'http' + style[start + 6:end]info = MovieDemoItem(src=src, film_name=film_name, lead_actor=all_actor)yield info

pipelines文件

class MovieDemoPipeline:def open_spider(self, spider):self.f = open('movie.json', 'w', encoding='utf-8')def process_item(self, item, spider):self.f.write(str(item) + ',')return itemdef end_spider(self, spider):self.f.close()import urllib.request
import randomclass MoviePicture:def process_item(self, item, spider):src = item.get('src')filename = 'posters/' + item.get('film_name') + '.jpg'# 在这里遇到了防爬,所以需要进行伪装ua_list = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.62','Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0']# 创建opener对象opener = urllib.request.build_opener()# 给opener添加请求头opener.addheaders = [('User-Agent', random.choice(ua_list))]# 将opener设置为全局安装urllib.request.install_opener(opener)urllib.request.urlretrieve(url=src, filename=filename)return item

7.10 post请求的使用

import scrapy
import jsonclass TranslateSpider(scrapy.Spider):name = 'translate'allowed_domains = ['fanyi.baidu.com']# start_urls = ['http://fanyi.baidu.com/sug']# def parse(self, response):#     pass"""这里的写法,和我们使用get请求就不一样了因为post请求需要携带参数,而start_urls第一次请求没有办法携带,导致parse函数接收不到response,所以注释掉"""def start_requests(self):url = 'http://fanyi.baidu.com/sug'data = {"kw": "hello"}# scrapy.FormRequest()就是post请求yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse_1)def parse_1(self, response):res = response.textprint(json.loads(res))

总结

以上就是今天要讲的内容,希望对大家有所帮助!!!


http://www.ppmy.cn/news/12576.html

相关文章

c语言实现扫雷(详细讲解)

本篇介绍,讲解如何使用c语言实现扫雷小游戏. 金句分享: ✨✨✨爱你所爱,行你所行✨✨✨ 目录前言:一、游戏设计思路介绍:效果展示二、游戏的分步讲解2.1、主函数测试区(test.c)基本构成2.2、游戏中函数实现区(game.c) (重点)2.21、雷盘的创建与初始化函…

【数据结构】手撕八大排序算法

作者:一个喜欢猫咪的的程序员 专栏:《数据结构》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 目录 1.排序的概念: 2.八大排序的思路及其细节 2.1直接插入排序 …

java springboot 项目构建报错解决办法

这里总结了一些常见的springboot 项目构建报错及解决办法 错误: 无效的源发行版:17 错误原因 build.gradle 文件中可以通过下面两项来指定项目运行所需的jdk版本 sourceCompatibility:指定编译编译.java文件的jdk版本 targetCompatibility:确保class文件与target…

回归预测 | MATLAB实现SSA-LSSVM麻雀算法优化最小二乘支持向量机多输入单输出

回归预测 | MATLAB实现SSA-LSSVM麻雀算法优化最小二乘支持向量机多输入单输出 目录回归预测 | MATLAB实现SSA-LSSVM麻雀算法优化最小二乘支持向量机多输入单输出预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 MATLAB实现SSA-LSSVM麻雀算法优化最小二乘支持向量机…

spring系列 SpringAOP

概念 原来的方法写法 public void save(){ Long startTime System.currentTimeMillis(); System.out.println(“book dao save ...”); Long endTime System.currentTimeMillis(); Long totalTime endTime-startTime; System.out.prin…

解决Vue3中使用setup如何定义组件的name属性

vue2的书写name: <template><div></div> </template><script> export default {name: "nameoption", }; </script><style lang"scss" scoped></style>解决&#xff1a;Vue3中使用setup如何定义组件的nam…

基于贝叶斯算法的邮件过滤管理系统的设计和实现(Vue+SpringBoot)

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

2个大厂 100亿级 超大流量 红包 架构方案

2个大厂 100亿级 超大流量 红包 架构方案 文章目录2个大厂 100亿级 超大流量 红包 架构方案100亿级 红包 应用 场景概述百亿级 微信红包技术架构架构**南北分布****拆红包入账异步化****发拆落地&#xff0c;其他操作双层cache**高并发**红包算法****柔性降级方案**360w QPS 10…