sheng的学习笔记-网络爬虫scrapy框架

基础知识:

scrapy介绍

何为框架,就相当于一个封装了很多功能的结构体,它帮我们把主要的结构给搭建好了,我们只需往骨架里添加内容就行。scrapy框架是一个为了爬取网站数据,提取数据的框架,我们熟知爬虫总共有四大部分,请求、响应、解析、存储,scrapy框架都已经搭建好了。scrapy是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架,scrapy使用了一种非阻塞的代码实现并发的

整体架构图

各组件:

数据处理流程

项目示例

环境搭建

下载依赖包

pip install wheel
下载twisted:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
安装twisted:pip install Twisted-17.1.0-cp36m-win_amd64.whl   (这个文件的路劲)
pip install pywin32
pip install scrapy
测试:在终端输入scrapy指令,没有报错表示安装成功
在anaconda中,可以直接装scrapy,会自动把依赖的包都装好

pyopenssl要改成22.0.0版本,否则调用request的时候报错,anaconda会自动改一下依赖的别的包的版本

创建项目

创建项目叫spider

1、打开pycharm的terminal
2、scrapy startproject spider    创建项目
3、cd spider
4、scrapy genspider douban www.xxx.com  创建爬虫程序  
5、需要有main.py里面的输出,则修改settings.py里面的ROBOTSTXT_OBEY = True改为False
6、scrapy crawl main
  不需要额外的输出则执行scrapy crawl main --nolog
   或者在settings.py里面添加LOG_LEVEL='ERROR',main.py有错误代码会报错(不添加有错误时则不会报错)(常用)

打开spider项目,里面有个spiders文件夹,称为爬虫文件夹,在这里放爬虫业务文件

项目代码

在douban.py里,写爬虫程序

此处是爬虫业务逻辑,爬到网站地址,对于爬虫返回结果的解析,在parse中做

根据应答的数据,解析,可以用xpath或者css解析,找到对应的数据

import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse

from spider.items import MovieItem


class DoubanSpider(scrapy.Spider):
    name = 'douban'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com/top250']

    def start_requests(self):
        for page in range(10):
            yield Request(url=f'https://movie.douban.com/top250?start={page * 25}&filter=')

    def parse(self, response: HtmlResponse, **kwargs):
        sel = Selector(response)
        list_items = sel.css("#content > div > div.article > ol > li")
        for list_item in list_items:
            movie_item = MovieItem()
            movie_item['title'] = list_item.css('span.title::text').extract_first()
            movie_item['rank'] = list_item.css('span.rating_num::text').extract_first()
            movie_item['subject'] = list_item.css('span.inq::text').extract_first()
            yield movie_item
        # href_list = sel.css('div.paginator > a::attr(href)')
        # for href in href_list:
        #     url =  response.urljoin(href.extract())

其中,将返回的值转化为对象,需要在item.py里改一下代码

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

#爬虫获取到到数据需要组装成item对象
class MovieItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    rank = scrapy.Field()
    subject = scrapy.Field()

执行爬虫

执行工程:scrapy crawl douban -o douban.csv (运行douban爬虫文件,并将结果生成到douban.csv里面)
如果被识别了是爬虫程序,在setting中设置一下user agent的值

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36' # User-Agent字符串

保存数据

默认可以支持保存到csv,json

保存到excel

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import openpyxl

#将爬虫返回的数据持久化,先存放到excel
class ExcelPipeline:
    # 创建excel工作簿和工作表
    def __init__(self):
        self.wb = openpyxl.Workbook()
        # wb.create_sheet()
        self.ws = self.wb.active  #激活工作表
        self.ws.title = "Top250"   #改名字
        self.ws.append(('标题','评分','主题'))

    def close_spider(self,spider):
        self.wb.save('电影数据.xlsx')

    # item就是数据
    def process_item(self, item, spider):
        title = item.get('title','')
        rank = item.get('rank', '')
        subject = item.get('subject', '')
        self.ws.append((title,rank,subject))
        return item

在setting.py中改一下配置,找到这个注释,去掉注释

前面是管道名称,如果多个管道,在这里配置多个值,数字小的先执行,数字大的后执行

值要和类名字一致,我改了名字

ITEM_PIPELINES = {
   'spider.pipelines.ExcelPipeline': 300,
}

运行命令。  scrapy crawl douban 

保存到数据库mysql

新增一个mysql的持久化逻辑,init的时候创建连接,process的时候插入,close的时候提交和关闭连接

建表语句

create table tb_top_move(
movie_id INT AUTO_INCREMENT PRIMARY KEY comment '编号',
title varchar(50) not null comment '标题',
rating decimal(3,1) not null comment '评分',
subject varchar(200) not null comment '主题'
) engine=innodb comment='Top电影表'
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import openpyxl
import pymysql


#将爬虫返回的数据持久化,先存放到mysql
class MysqlPipeline:
    # 创建excel工作簿和工作表
    def __init__(self):
        #todo 设置db信息
        self.conn = pymysql.connect(host='127.0.0.1',port=,user='',password='',database='',charset='utf8mb4')
        self.cursor = self.conn.cursor()

    def close_spider(self,spider):
        self.conn.commit()
        self.conn.close()
    # item就是数据
    def process_item(self, item, spider):
        title = item.get('title', '')
        rank = item.get('rank', 0)
        subject = item.get('subject', '')
        self.cursor.execute('insert into tb_top_move(title,rating,subject) values (%s,%s,%s)',
                            (title,rank,subject))
        return item

#将爬虫返回的数据持久化,先存放到excel
class ExcelPipeline:
    # 创建excel工作簿和工作表
    def __init__(self):
        self.wb = openpyxl.Workbook()
        # wb.create_sheet()
        self.ws = self.wb.active  #激活工作表
        self.ws.title = "Top250"   #改名字
        self.ws.append(('标题','评分','主题'))

    def close_spider(self,spider):
        self.wb.save('电影数据.xlsx')

    # item就是数据
    def process_item(self, item, spider):
        title = item.get('title','')
        rank = item.get('rank', '')
        subject = item.get('subject', '')
        self.ws.append((title,rank,subject))
        return item

改下setting的配置

ITEM_PIPELINES = {
   'spider.pipelines.MysqlPipeline': 200,
   'spider.pipelines.ExcelPipeline': 300,
}

如果需要代理,可以用这种方式,在douban的py中修改

运行爬虫

scrapy crawl douban

多层爬虫

在爬了第一个页面,跟进内容爬第二个页面,比如在第一个汇总页面,想要知道《霸王别姬》中的时长和介绍,要点进去看到第二个页面

核心是douban.py中,parse函数yield返回的,是一个新的请求,并通过parse_detail作为回调函数进行第二层页面的解析

代码:

douban.py

import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse

from spider.items import MovieItem


class DoubanSpider(scrapy.Spider):
    name = 'douban'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com/top250']

    def start_requests(self):
        for page in range(1):
            yield Request(url=f'https://movie.douban.com/top250?start={page * 25}&filter=')

    def parse(self, response: HtmlResponse, **kwargs):
        sel = Selector(response)
        list_items = sel.css("#content > div > div.article > ol > li")
        for list_item in list_items:
            detail_url = list_item.css("div.info > div.hd > a::attr(href)").extract_first()
            movie_item = MovieItem()
            movie_item['title'] = list_item.css('span.title::text').extract_first()
            movie_item['rank'] = list_item.css('span.rating_num::text').extract_first()
            movie_item['subject'] = list_item.css('span.inq::text').extract_first() or ''
            # yield movie_item
            yield Request(url=detail_url, callback=self.parse_detail,
                          cb_kwargs={'item':movie_item}
                          )
        # href_list = sel.css('div.paginator > a::attr(href)')
        # for href in href_list:
        #     url =  response.urljoin(href.extract())

    def parse_detail(self,response,**kwargs):
        movie_item = kwargs['item']
        sel = Selector(response)
        movie_item['duration']=sel.css('span[property="v:runtime"]::attr(content)').extract()
        movie_item['intro']=sel.css('span[property="v:summary"]::text').extract_first() or ''
        yield movie_item

/items.py

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

#爬虫获取到到数据需要组装成item对象
class MovieItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    rank = scrapy.Field()
    subject = scrapy.Field()
    duration = scrapy.Field()
    intro = scrapy.Field()

/pipelines.py

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import openpyxl
import pymysql

'''
建表语句
create table tb_top_move(
movie_id INT AUTO_INCREMENT PRIMARY KEY comment '编号',
title varchar(50) not null comment '标题',
rating decimal(3,1) not null comment '评分',
subject varchar(200) not null comment '主题',
duration int comment '时长',
intro varchar(10000) comment '介绍'
) engine=innodb comment='Top电影表'
'''

#将爬虫返回的数据持久化,先存放到excel
class MysqlPipeline:
    # 创建excel工作簿和工作表
    def __init__(self):
        #todo 设置db信息
        self.conn = pymysql.connect(host='127.0.0.1',port=3306,
                                    user='lzs_mysql',password='lzs',database='mysql',charset='utf8mb4')
        self.cursor = self.conn.cursor()

    def close_spider(self,spider):
        self.conn.commit()
        self.conn.close()
    # item就是数据
    def process_item(self, item, spider):
        title = item.get('title', '')
        rank = item.get('rank', 0)
        subject = item.get('subject', '')
        duration = item.get('duration', '')
        intro = item.get('intro', '')
        self.cursor.execute('insert into tb_top_move(title,rating,subject,duration,intro) values (%s,%s,%s,%s,%s)',
                            (title,rank,subject,duration,intro))
        return item

#将爬虫返回的数据持久化,先存放到excel
class ExcelPipeline:
    # 创建excel工作簿和工作表
    def __init__(self):
        self.wb = openpyxl.Workbook()
        # wb.create_sheet()
        self.ws = self.wb.active  #激活工作表
        self.ws.title = "Top250"   #改名字
        self.ws.append(('标题','评分','主题'))

    def close_spider(self,spider):
        self.wb.save('电影数据.xlsx')

    # item就是数据
    def process_item(self, item, spider):
        title = item.get('title','')
        rank = item.get('rank', '')
        subject = item.get('subject', '')
        self.ws.append((title,rank,subject))
        return item

运行爬虫

scrapy crawl douban

中间件

中间件分为蜘蛛中间件和下载中间件

蜘蛛中间件一般不动

如果想要在请求中加上cookie,可以在中间件上的请求加上cookie信息

在middlewares.py类中,加上一个方法,获取cookie信息

修改middle的类

修改配置setting

参考文章:

02.使用Scrapy框架-1-创建项目_哔哩哔哩_bilibili

https://www.cnblogs.com/12345huangchun/p/10501673.html

Scrapy框架(高效爬虫)_scrapy爬虫框架-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/383310.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之AlphabetIndexer组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之AlphabetIndexer组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、AlphabetIndexer组件 可以与容器组件联动用于按逻辑结构快速定位容器显…

C#使用重载方法实现不同类型数据的计算

目录 一、涉及到的相关知识 1.重载的方法 2.Convert.ToInt32(String)方法 3.判断字符串是否带有小数点 二、实例 1.示例 2.生成成果 一、涉及到的相关知识 1.重载的方法 重载方法就是方法名称相同,但是每个方法中参数的数据类型、个数或顺序不同的方法。如果…

【电路】三个晶体管的声控开关电路

这种声控开关,可能是非常有用的,例如敲门声或拍手声可以激活一盏灯,灯光几秒钟后会自动关闭。另一种使用在防盗保护,如果有人想打开门或打破东西,灯就会亮起来,这表明有人在家。 该电路可以工作于任何5–1…

disql备份还原

disql备份还原 前言 本文档根据官方文档,进行整理。 一、概述 在 disql 工具中使用 BACKUP 语句你可以备份整个数据库。通常情况下,在数据库实例配置归档后输入以下语句即可备份数据库: BACKUP DATABASE BACKUPSET db_bak_01;语句执行完…

使用Cargo创建、编译与运行Rust项目

在 Rust 开发中,Cargo 是一个非常重要的工具,它负责项目的构建、管理和依赖管理。以下是如何使用 Cargo 创建、编译和运行 Rust 项目的详细步骤。 1. 创建新项目 首先确保你已经在计算机上安装了 Rust 和 Cargo。然后,在命令行中输入以下命…

【动态规划】1301. 最大得分的路径数目

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 LeetCoce1301. 最大得分的路径数目 给你一个正方形字符数组 board ,你从数组最右下方的字符 ‘S’ 出发。 你的目标是到达数组最左上角的字符 ‘E’ ,数组剩余…

【Tauri】(1):使用Tauri1.5版本,进行桌面应用开发,在windows,linux进行桌面GUI应用程序开发,可以打包成功,使用 vite 最方便

1,视频地址: https://www.bilibili.com/video/BV1Pz421d7s4/ 【Tauri】(1):使用Tauri1.5版本,进行桌面应用开发,在windows,linux进行桌面GUI应用程序开发,可以打包成功&…

springboot177健身房管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

Java图形化界面编程——弹球游戏 笔记

Java也可用于开发一些动画。所谓动画,就是间隔一定的时间(通常小于0 . 1秒 )重新绘制新的图像,两次绘制的图像之间差异较小,肉眼看起来就成了所谓的动画 。 ​ 为了实现间隔一定的时间就重新调用组件的 repaint()方法,可以借助于…

正则可视化工具:学习和编写正则表达式的利器

引言 正则表达式是一种强大的文本匹配和处理工具,但对于初学者和非专业开发者来说,编写和理解正则表达式可能是一项具有挑战性的任务。为了帮助人们更好地学习和编写正则表达式,正则可视化工具应运而生。本文将探讨正则可视化工具的优点&…

自动化AD域枚举和漏洞检测脚本

linWinPwn 是一个 bash 脚本,可自动执行许多 Active Directory 枚举和漏洞检查。该脚本基于很多现有工具实现其功能,其中包括:impacket、bloodhound、netexec、enum4linux-ng、ldapdomaindump、lsassy、smbmap、kerbrute、adidnsdump、certip…

力扣49. 字母异位词分组

Problem: 49. 字母异位词分组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.我们利用一个无序映射以排序后的字符作为键、字符数组作为值; 2.每次我们从原始数组中取出一个字符串并对其进行排序,并将其添加到对应键所存的数组中; 3.创建…

OpenAI---提示词工程的6大原则

OpenAI在官方的文档里上线了Prompt engineering,也就是提示词工程指南,其中OpenAI有提到写提示词的6条大的原则,它们分别是: (1)Write clear instructions(写出清晰的指令) &#xf…

【漏洞复现】狮子鱼CMS文件上传漏洞(wxapp.php)

Nx01 产品简介 狮子鱼CMS(Content Management System)是一种网站管理系统,它旨在帮助用户更轻松地创建和管理网站。该系统拥有用户友好的界面和丰富的功能,包括页面管理、博客、新闻、产品展示等。通过简单直观的管理界面&#xf…

Java的接口

目录 1.接口的概念 2.语法规则 3.接口的使用 4.接口的特性 总结: 5.实现多个接口 6.接口间的继承 1.接口的概念 接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。 在Java中,接口可以看成…

学习Android的第十天

目录 Android CheckBox 复选框 获得选中的 CheckBox 的值 自定义点击效果 改变文字与选择框的相对位置 修改文字与选择框的距离 Android ToggleButton 开关按钮 改变 ToggleButton 的状态和文本 Android Switch 开关 改变 Switch 的状态和文本 Android CheckBox 复选框…

Vue源码系列讲解——模板编译篇【一】(综述)

目录 1. 前言 2. 什么是模板编译 3. 整体渲染流程 4. 模板编译内部流程 4.1 抽象语法树AST 4.2 具体流程 5. 总结 1. 前言 在前几篇文章中,我们介绍了Vue中的虚拟DOM以及虚拟DOM的patch(DOM-Diff)过程,而虚拟DOM存在的必要条件是得先有VNode&…

ChatGPT高效提问—prompt常见用法(续篇五)

ChatGPT高效提问—prompt常见用法(续篇五) 1.1 种子词 ​ 种子词(seed word)通常指的是在对话中使用的初始提示或关键词,用于引导ChatGPT生成相关回复。种子词可以是一个词、短语或句子,通常与对话的主题…

VTK 三维场景的基本要素(相机) vtkCamera

观众的眼睛好比三维渲染场景中的相机,在VTK中用vtkCamera类来表示。vtkCamera负责把三维场景投影到二维平面,如屏幕,相机投影示意图如下图所示。 1.与相机投影相关的要素主要有如下几个: 1)相机位置: 相机所处的位置…

Vue3中Setup概述和使用(三)

一、引入Setup 1、Person.Vue 与Vue3编写简单的App组件(二) 中的区别是&#xff1a;取消data、methods等方法,而是将数据和方法定义全部放进setup中。 <template><div class"person"><h1>姓名:{{name}}</h1><h1>年龄:{{age}}</h…