python爬虫快速入门之---Scrapy 从入门到包吃包住

python爬虫快速入门之—Scrapy 从入门到包吃包住

文章目录

    • python爬虫快速入门之---Scrapy 从入门到包吃包住
      • 一、scrapy简介
        • 1.1、scrapy是什么?
        • 1.2、Scrapy 的特点
        • 1.3、Scrapy 的主要组件
        • 1.4、Scrapy 工作流程
        • 1.5、scrapy的安装
      • 二、scrapy项目快速入门
        • 2.1、scrapy项目快速创建以及运行
          • 2.1.1、创建爬虫项目
          • 2.1.2、创建爬虫文件
          • 2.1.3、运行爬虫代码
          • 2.1.4、修改遵守robots协议
        • 2.2、scrapy项目
          • 2.2.1、文件结构
          • 2.2.2、parse方法中的response属性和方法
          • 2.2.3、scrapy的工作原理
        • 2.3、yield关键字
      • 三、scrapy shell
        • 3.1、scrapy shell简介
        • 3.2、进入scrapy shell
        • 3.3、scrapy shell的基本使用
      • 四、scrapy项目实战--抓取商品数据并保存
        • 4.1、创建项目
        • 4.2、定义item数据结构
        • 4.3、编写爬虫文件
        • 4.4、编写pipeline管道
        • 4.5、单管道运行查看
        • 4.6、多管道的编写
          • 4.6.1、定义广告类
          • 4.6.2、在setting中开启管道
          • 4.6.3、启动测试
        • 4.7、下载多页数据
      • 五、scrapy项目实战--网页嵌套处理
      • 六、CrawlSpider
        • 6.1、简介
        • 6.2、链接提取器
      • 七、CrawlSpider案例实战
        • 7.1、项目初始化
        • 7.2、改造项目
        • 7.3、运行并查看结果
      • 八、联动mysql数据库持久化到本地
        • 8.1、安装pymysql
        • 8.2、创建mysql数据库
        • 8.3、编写配置
        • 8.4、编写数据库持久化管道类
        • 8.5、开启管道
        • 8.6、测试并观察数据库中保存的结果
      • 九、日志与日志文件
      • 十、scrapy的post请求
      • 十一、scrapy的代理
        • 11.1、 **在 `settings.py` 中配置代理**
        • 11.2、 **自定义代理中间件**
        • 11.3、 **为特定请求设置代理**
        • 11.4、 **使用第三方代理服务**

一、scrapy简介

1.1、scrapy是什么?

image-20241016174358800

官方文档:https://scrapy.org/

scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。
可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

Scrapy 是一个开源的 Python 爬虫框架,用于从网站上提取数据(即进行网络爬虫),并能将这些数据进行处理和存储。
它的设计目标是简单高效地抓取大量网页,并提供强大的工具来进行数据的提取和分析。

1.2、Scrapy 的特点
  • 快速开发:Scrapy 提供了许多内置功能,帮助开发者快速构建高效的爬虫程序。
  • 可扩展性强:它允许用户自定义中间件、管道等,满足各种爬虫需求。
  • 异步处理:Scrapy 使用 Twisted 异步网络库,可以同时处理大量请求,从而加快爬虫的效率。
  • 数据处理方便:支持将数据保存为多种格式,例如 JSON、CSV、XML 等。
1.3、Scrapy 的主要组件
  • Spider(爬虫):这是用户定义的类,用于指定如何从某个或多个网站抓取数据以及如何解析和处理这些数据。
  • Selectors(选择器):Scrapy 提供了强大的选择器工具(如 XPath、CSS 选择器),用于从 HTML 页面中提取数据。
  • Item(数据容器):类似于一个数据结构,用来定义要从网页中抓取和存储的数据。
  • Pipeline(数据管道):用于对抓取到的数据进行后续处理,如清洗、验证、存储等。
  • Middleware(中间件):在请求和响应的处理中,可以通过中间件对其进行拦截和处理,比如修改 headers、处理 cookies 等。
1.4、Scrapy 工作流程
  • 发送请求:Spider 定义了要抓取的网站地址。Scrapy 通过异步方式发送请求。
  • 接收响应:收到响应后,通过 Spider 定义的回调方法处理响应数据。
  • 数据提取:利用 Scrapy 提供的选择器工具提取目标数据。
  • 保存数据:提取到的数据会通过管道处理,进行清洗、存储或输出
1.5、scrapy的安装

懒得记笔记,直接上连接:https://blog.csdn.net/qq_45476428/article/details/108739943

  • 如果报错twisted:
    http://www.1fd.uci.edu/~gohlke/pythonlibs/#twisted
  • 也可以使用anaconda安装环境:
    https://docs.anaconda.com/anaconda/install/windows

二、scrapy项目快速入门

2.1、scrapy项目快速创建以及运行
2.1.1、创建爬虫项目

切换到一个你想存放项目的文件夹,并进入命令行,使用命令来创建一个scrapy项目。

命令如下:

scrapy startproject scrapy_study_01

其中scrapy_study_01是项目的名字,项目的名字不允许使用数字开头,也不能包含中文。

image-20241015093209629

从而可以在目录下看到这个项目:

image-20241015093251134

然后使用我们的ide来打开这个项目:

image-20241015093642918

2.1.2、创建爬虫文件

要在spiders文件夹中去创建爬虫文件

命令:cd 项目的名字\项目的名字\spiders

cd scrapy_study_01\scrapy_study_01\spiders

创建爬虫文件:scrapy genspider 爬虫文件的名字 要爬取网页

scrapy genspider baidu http://www.baidu.com

一般情况下不需要添加http协议

image-20241015094320532

可以看到新创建的文件:

import scrapyclass BaiduSpider(scrapy.Spider):# 爬虫名称name = "baidu"# 允许的域名allowed_domains = ["www.baidu.com"]# 起始url 在allowed_domains的前面添加了http://start_urls = ["http://www.baidu.com"]# 是执行了start_urls之后 执行的方法 方法中的response就是返回的那个对象# 相当于response = urllib.request.urlopen()#    和 response = requests.get()def parse(self, response):print("我是一个百度的爬虫程序")
2.1.3、运行爬虫代码

语法:scrapy crawl 爬虫的名字

scrapy crawl baidu

image-20241015095225729

当我运行爬虫的代码的时候,并没有执行我的print("我是一个百度的爬虫程序")语句,这可以网站就做了一些反扒的手段。

怎么处理:

  1. 百度的robots.txt协议:

    根据下图可以看到百度是不允许爬虫的

    image-20241015095535989

2.1.4、修改遵守robots协议

打开项目下的settings.py文件,把这句ROBOTSTXT_OBEY = True代码注释即可,意为不遵守robots协议。

image-20241015095754774

然后再次运行代码:

scrapy crawl baidu

发现我们的语句执行了:

image-20241015100008115

2.2、scrapy项目
2.2.1、文件结构

image-20241015100905334

2.2.2、parse方法中的response属性和方法
属性和方法意义
response.text获取的是响应的字符串
response.body获取的是二进制数据
response.xpath可以直接是xpath方法来解析response中的内容
response.extract()提取seletor对象的data属性值
response.extract_first()取的seletor列表的第-个数据

可以使用下面这个58同城的案例来测试:

  1. 创建项目

    scrapy startproject scrapy_study_02
    
  2. 创建爬虫文件

    cd scrapy_study_02\scrapy_study_02\spiders
    
    scrapy genspider tc "https://bj.58.com/sou/?key=%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91&classpolicy=uuid_c84b556016c34f2392cf3772a0ff84d3%2Cclassify_B&search_uuid=c84b556016c34f2392cf3772a0ff84d3"
    

    上述网址来源于:58同城

    image-20241015103845101

  3. 修改遵守robots协议

    image-20241015103730691

修改tc.py文件来查看response参数里面的内容:

import scrapyclass TcSpider(scrapy.Spider):name = "tc"allowed_domains = ["bj.58.com"]start_urls = ["https://bj.58.com/sou/?key=%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91&classpolicy=uuid_c84b556016c34f2392cf3772a0ff84d3%2Cclassify_B&search_uuid=c84b556016c34f2392cf3772a0ff84d3"]def parse(self, response):html= response.textprint("*******************************")print(html)

运行python文件:

 scrapy crawl tc  

查看控制台的打印结果,发现就是我们需要的网页:

image-20241015105444018

所以现在总结一下response的属性和方法:

属性和方法意义
response.text获取的是响应的字符串
response.body获取的是二进制数据
response.xpath可以直接是xpath方法来解析response中的内容
response.extract()提取seletor对象的data属性值
response.extract_first()取的seletor列表的第-个数据
2.2.3、scrapy的工作原理

img

引擎(Engine)
引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。 详细内容查看下面的数据流(Data Flow)部分。

调度器(Scheduler)
调度器从引擎接受request并将他们入队,以便之后引擎请求他们时提供给引擎。

下载器(Downloader)
下载器负责获取页面数据并提供给引擎,而后提供给spider

爬虫(Spiders)
SpiderScrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些)网站。

项目管道(Item Pipeline)
Item Pipeline负责处理被spider提取出来的item。典型的处理有清理、 验证及持久化(例如存取到数据库中)。

下载器中间件(Downloader middlewares)
下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的response。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。

爬虫中间件(Spider middlewares)
Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。

简言之可以总结为下面几点:

  1. 引擎向spiders要url
  2. 引擎将要爬取的ur给调度器
  3. 调度器会将ur生成请求象放入到指定的队列中
  4. 从队列中出队一个请求
  5. 引擎将请求交给下载器进行处理
  6. 下载器发送请求获取互联网数据
  7. 下载器将数据返回给引擎
  8. 引擎将数据再次给到spiders
  9. spiders通过xpath解析该数据,得到数据或者url
  10. spiders将数据或者url给到引擎
  11. 引擎判断该数据还是url,是数据,交给管道(item pipeline)处理,是url交给调度器处理
2.3、yield关键字
  1. 带有yield的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
  2. yield是一个类似return的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行
  3. 简要理解:yield就是return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始

三、scrapy shell

3.1、scrapy shell简介

Scrapy shell是一个交互式shell(终端),您可以在其中快速调试您的抓取代码,而无需运行spider。它旨在用于测试数据提取代码,但您实际上可以将其用于测试任何类型的代码,因为它也是一个常规的Python shell。

shell用于测试XPath或CSS表达式,看看它们是如何工作的,以及它们从您试图抓取的网页中提取了什么数据。它允许您在编写spider时交互式地测试表达式,而无需运行spider来测试每一个更改。

一旦你熟悉了Scrapy shell,你就会发现它是开发和调试spider的宝贵工具。

scrapy shell官方文档

3.2、进入scrapy shell

进入到scrapy shell的终端直接在window的终端中输入scrapy shell 域名

即:

scrapy shell www.baidu.com

image-20241015145001725

如果想看到一些高亮或者自动补全那么可以安装ipython,使用命令安装:

pip install ipython
3.3、scrapy shell的基本使用

可用的方法

  • shelp(): 打印可用的对象和方法
  • fetch(url[, redirect=True]): 爬取新的 URL 并更新所有相关对象
  • fetch(request): 通过给定request 爬取,并更新所有相关对象
  • view(response): 使用本地浏览器打开给定的响应。这会在计算机中创建一个临时文件,这个文件并不会自动删除

可用的Scrapy对象

Scrapy shell自动从下载的页面创建一些对象,如 Response 对象和 Selector 对象。这些对象分别是

  • crawler: 当前Crawler 对象
  • spider: 爬取使用的 Spider,如果没有则为Spider对象
  • request: 最后一个获取页面的Request对象,可以使用 replace() 修改请求或者用 fetch() 提取新请求
  • response: 最后一个获取页面的Response对象
  • settings: 当前的Scrapy设置

例如使用response

  • response.body

    image-20241015151912683

  • response.text

    image-20241015151942484

  • response.url

    image-20241015152003345

  • response.status

    image-20241015152515921

  • response.xpath('//input[@id="su"]/@value')

    image-20241015152709759

四、scrapy项目实战–抓取商品数据并保存

案例背景: 获取一个购物网页的一些数据,例如标题、图片、价格等。

4.1、创建项目

根据本篇博客的2.1部分内容来进行创建,其中创建爬虫文件关键的语句为:

scrapy genspider dang https://category.dangdang.com/cp01.01.01.00.00.00.html 
4.2、定义item数据结构
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass ScrapyStudy04DangdangItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 价格price = scrapy.Field()# 标题title = scrapy.Field()# 图片img_url = scrapy.Field()
4.3、编写爬虫文件
import scrapy
from scrapy_study_04_dangdang.items import ScrapyStudy04DangdangItemclass DangSpider(scrapy.Spider):name = "dang"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.01.01.00.00.00.html"]def parse(self, response):# pipelines 存储数据# item 定义数据li_list = response.xpath("//ul[@id='component_59']/li")for li in li_list:title = li.xpath(".//a[1]/@title").extract_first()price = li.xpath(".//p[3]/span[1]/text()").extract_first()img = li.xpath(".//img/@data-original").extract_first()if img:img = imgelse:img = li.xpath(".//img/@src").extract_first()  # 防止出现没有data-original数据的情况book = ScrapyStudy04DangdangItem(img_url=img, title=title, price=price)# 获取一个book就将book交给pipelinesyield book

其中通过yield关键字将我们需要的book数据对象传输到pipelines中,方便我们进行数据处理。

而关键语句book = ScrapyStudy04DangdangItem(img_url=img, title=title, price=price)可以看出我们的语句是来自items.py文件。

4.4、编写pipeline管道

在使用这个文件之前,需要先在setting.py中开启这个功能:

image-20241015172119920

即:

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {"scrapy_study_04_dangdang.pipelines.ScrapyStudy04DangdangPipeline": 300,
}
  • 其中管道可以有很多个;
  • 管道是有优先级的,优先级的范围是1-1000 ;
  • 取值越小的优先级越高。

现在我们就可以将我们的数据进行处理(保存成json文件):

# 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# 如果需要使用pipeline,需要现在setting中开启
class ScrapyStudy04DangdangPipeline:# item: yield 后面的book对象def process_item(self, item, spider):with open("book.json", "a", encoding="utf-8") as f:f.write(str(item))return item

实际操作的时候要注意以下几个问题:

(1)write里面必须传入字符串,所以需要先转成字符串

(2)写入文件的w模式,每次写入都会覆盖之前的数据,所以把w改成a(追加)

缺点:每次写入都会打开文件,然后关闭文件,效率不高

优化版pipelines

# 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# 如果需要使用pipeline,需要现在setting中开启
class ScrapyStudy04DangdangPipeline:# 爬虫文件执行之前def open_spider(self, spider):self.fp = open("book.json", "w", encoding="utf-8")# item: yield 后面的book对象def process_item(self, item, spider):# 优化版self.fp.write(str(item))# 爬虫文件执行之后def close_spider(self, spider):self.fp.close()

经过上述这种写法的优化之后,就改变了频繁的打开和关闭文件的操作,其中两个方法分别对应的是爬虫文件执行之前之后执行。

4.5、单管道运行查看

根据上述代码的方式来编写项目,起始就是一个单管道的一种模式。

运行结果:

image-20241015172538870

4.6、多管道的编写

在上述代码的基础上,再添加一些代码即可实现多管道的编写

4.6.1、定义广告类

在pipelines.py文件上新建一个ScrapyDangdangDownloadPipeline类,用来下载图片资源:

class ScrapyDangdangDownloadPipeline:# 这个方法源自上面这个类的process_item方法def process_item(self, item, spider):url = item.get("img_url")filename = './books/' + item.get("title") + ".jpg"urllib.request.urlretrieve(url, filename)return item
4.6.2、在setting中开启管道

打开settings.py文件,找到ITEM_PIPELINES这个参数,并在里面添加ScrapyDangdangDownloadPipeline参数如下:

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {# 管道可以有很多个,管道是有优先级的,优先级的范围是1-1000 值越小的优先级越高"scrapy_study_04_dangdang.pipelines.ScrapyStudy04DangdangPipeline": 300,# ScrapyDangdangDownloadPipeline"scrapy_study_04_dangdang.pipelines.ScrapyDangdangDownloadPipeline": 301,
}
4.6.3、启动测试

输入命令启动多管道项目:

scrapy crawl dang

就会发现新产生的json文件和图片资源文件:

image-20241016094939556

需要注意的是,books文件夹需要手动添加。

4.7、下载多页数据

多页的爬取的业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法

但是首先需要观察每页变化的逻辑:

https://category.dangdang.com/pg1-cp01.01.07.00.00.00.html
https://category.dangdang.com/pg2-cp01.01.07.00.00.00.html
https://category.dangdang.com/pg6-cp01.01.07.00.00.00.html
https://category.dangdang.com/pg100-cp01.01.07.00.00.00.html

改造原来的dang.py文件里面的parse函数

import scrapy
from scrapy_study_04_dangdang.items import ScrapyStudy04DangdangItemclass DangSpider(scrapy.Spider):name = "dang"# 这里只写域名,在旧版本上面会自动添加原始请求,但是在请求多个页面,不同接口的时候这里只能写域名allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.01.01.00.00.00.html"]base_url = "https://category.dangdang.com/pg"page = 1def parse(self, response):# pipelines 存储数据# item 定义数据li_list = response.xpath("//ul[@id='component_59']/li")sfor li in li_list:title = li.xpath(".//a[1]/@title").extract_first()# detail = li.xpath(".//p[1]/a/text()").extract_first()price = li.xpath(".//p[3]/span[1]/text()").extract_first()img = li.xpath(".//img/@data-original").extract_first()if img:img = imgelse:img = li.xpath(".//img/@src").extract_first()  # 防止出现没有data-original数据的情况book = ScrapyStudy04DangdangItem(img_url="https:" + img, title=title, price=price)# 获取一个book就将book交给pipelinesyield bookif self.page <= 100:url = self.base_url + str(self.page) + "-cp01.01.07.00.00.00.html"self.page += 1# 调用parse函数get请求# scrapy.Request就是scrapy的# url 就是请求地址# callback 回调函数(即需要调用的函数,后面不用加())yield scrapy.Request(url=url, callback=self.parse)

具体细节在上述代码的注释上面存在,请仔细阅读。

最后启动测试即可:

scrapy crawl dang

image-20241016101048645

image-20241016101510793

五、scrapy项目实战–网页嵌套处理

根据本篇博客的2.1部分内容来进行创建,其中创建爬虫文件关键的语句为:

scrapy genspider mv https://btwuji.com/html/gndy/index.html

起始其他逻辑都与本博客第四模块差不多,主要就是网页嵌套的请求发起,当我们点击另一个链接的时候又需要对其发起请求,大致逻辑如下:

import scrapy
from scrapy_study_05_movie.items import ScrapyStudy05MovieItemclass MvSpider(scrapy.Spider):name = "mv"allowed_domains = ["btwuji.com"]start_urls = ["https://btwuji.com/html/gndy/index.html"]def parse(self, response):list = "//div[@class='co_content8']//td[1]/a[2]"for i in response.xpath(list):# 获取第二页urlurl = "https://btwuji.com/" + i.xpath("./@href").extract_first()# 获取电影名称name = i.xpath("./text()").extract_first()# 对第二页url进行请求yield scrapy.Request(url=url, callback=self.parse_second, meta={"name": name})def parse_second(self, response):img_src = response.xpath("//div[@id='Zoom']//img/@src").extract_first()  # 需要注意的是span不能识别到# print(img_src)name = response.meta["name"]movie = ScrapyStudy05MovieItem(name=name, src=img_src)yield movie  # 将数据返回给管道

其中主要的重点就是:

对第二页url进行请求:

yield scrapy.Request(url=url, callback=self.parse_second, meta={"name": name})

六、CrawlSpider

6.1、简介

CrawlSpider 是 Scrapy 框架中的一个常用类,专门用于编写爬取网站的规则导向型爬虫。

它继承自 Scrapy 的 Spider 类,并提供了更灵活的机制来处理复杂的网站导航结构。

相对于基础的 Spider,CrawlSpider 允许你定义一系列规则(rules),通过这些规则,爬虫可以自动跟踪链接并处理页面。

所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用crawlspider是非常合适的

6.2、链接提取器

在链接提取器里面可以写规则来提取我们想要的链接列表。

使用之前需要先导入

from scrapy.linkextractors  import LinkExtractor

语法:

操作含义
allow =()正则表达式提取符合正则的链接
deny =()正则表达式不提取符合正则的链接(不常用)
allow_domains =()允许的域名(不常用)
deny_domains =()不允许的域名(不常用)
restrict_xpaths =()xpath,提取符合xpath规则的链接
restrict_css =()提取符合选择器规则的链接(不推荐)

示例:

from scrapy.linkextractors  import LinkExtractorlink = LinkExtractor(allow=r'/book/1188_\d+\.html')
link.extract_links(response)

r'/book/1188_\d+\.html',其中,r是忽略转义的字符。

输出所有符合正则表达式的链接:

image-20241016154034501

七、CrawlSpider案例实战

需求:某读书网站数据入库

7.1、项目初始化
  1. 新建项目

    scrapy startproject scrapy_study_06_dushu
    
  2. 创建爬虫类

    cd .\scrapy_study_06_dushu\scrapy_study_06_dushu\spiders\
    scrapy genspider -t crawl read https://www.dushu.com/book/1188.html
    
    • 其中 -t参数的意义就是会给我们多新增加一些内容,利于我们使用CrawlSpider。
    • 还有follow参数:follow=true 是否跟进就是按照提取连接规则进行提取(如果是True将会一直爬取数据直至最后一页。)

    image-20241016155442157

7.2、改造项目
  1. 爬虫文件:

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from scrapy_study_06_dushu.items import ScrapyStudy06DushuItemclass ReadSpider(CrawlSpider):name = "read"allowed_domains = ["www.dushu.com"]# 原网页是1188但是不符合我们下面的正则规则,所以原网页会丢失,现在改成1188_1start_urls = ["https://www.dushu.com/book/1188_1.html"]rules = (Rule(LinkExtractor(allow=r"/book/1188_\d+\.html"),callback="parse_item",follow=False),)def parse_item(self, response):img_list = response.xpath("//div[@class='bookslist']//img")for img in img_list:name = img.xpath("./@alt").extract_first()src = img.xpath("./@data-original").extract_first()book = ScrapyStudy06DushuItem(name=name, src=src)yield book
    
  2. items文件

    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass ScrapyStudy06DushuItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()name = scrapy.Field()src = scrapy.Field()
    
  3. pipelines文件

    # 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 ItemAdapterclass ScrapyStudy06DushuPipeline:def open_spider(self, spider):self.fp = open("dushu.json", "w", encoding="utf-8")def process_item(self, item, spider):self.fp.write(str(item))return itemdef close_spider(self, spider):self.fp.close()
    
  4. 在setting.py中打开设置

    image-20241016163349045

7.3、运行并查看结果

image-20241016163448095

八、联动mysql数据库持久化到本地

案例就是第七章的内容继续改造。

8.1、安装pymysql

使用命令在python的安装目录下

pip install pmysql
8.2、创建mysql数据库

sql语句:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for spider01
-- ----------------------------
DROP TABLE IF EXISTS `spider01`;
CREATE TABLE `spider01`  (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`src` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 521 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

image-20241016170441611

不懂MySQL的安装和使用的朋友先去简单入门一下mysql,我这里就直接放上数据库的字段和sql语句。

推荐快速入门的教程:mysql的安装

8.3、编写配置

settings.py文件中的任意位置编写配置的参数信息:

# 数据库连接参数
DB_HOST = "localhost"
DB_PORT = 3306
DB_USER = 'root'
DB_PASSWORD = 'toor'
DB_NAME = 'spider1'
DB_CHARSET = 'utf8'

注意:必须要是与自己数据库参数对应才行。

8.4、编写数据库持久化管道类
# 加载settings数据
from scrapy.utils.project import get_project_settings
import pymysqlclass MysqlPipeline:def open_spider(self, spider):settings = get_project_settings()self.host = settings['DB_HOST']self.port = settings['DB_PORT']self.db = settings['DB_NAME']self.user = settings['DB_USER']self.password = settings['DB_PASSWORD']self.charset = settings['DB_CHARSET']self.conn = pymysql.connect(host=self.host,port=self.port,db=self.db,user=self.user,password=self.password,charset=self.charset)self.cursor = self.conn.cursor()def process_item(self, item, spider):# 编写插入数据的sql语句sql = 'insert into spider01(name,src) values("{}","{}")'.format(item['name'], item['src'])# 执行sql语句self.cursor.execute(sql)# 提交数据self.conn.commit()return itemdef close_spider(self, spider):self.cursor.close()self.conn.close()
8.5、开启管道

将数据库持久化的管道类在setting.py配置文件中进行配置

ITEM_PIPELINES = {"scrapy_study_06_dushu.pipelines.ScrapyStudy06DushuPipeline": 300,"scrapy_study_06_dushu.pipelines.MysqlPipeline": 301,
}
8.6、测试并观察数据库中保存的结果

image-20241016171556383

九、日志与日志文件

科普一下日志级别相关信息:

  • CRITICAL:严重错误

  • ERROR:般错误

  • WARNING:警告

  • INFO:一般信息

  • DEBUG:调试信息

    默认的日志等级是DEBUG

    只要出现了DEBUG或者DEBUG以上等级的日志

    那么这些日志将会打印

对于scrapy的日志管理在setting.py文件中可以进行设置

  • 默认的级别为DEBUG,会显示上面所有的信息
  • 在配置文件中settings·py
  • LOG_FILE:将屏幕显示的信息全部记录到文件中,屏幕不再显示,注意文件后缀一定是.log
  • LOG_LEVEL:设置日志显示的等级,就是显示哪些,不显示哪些

具体配置如下:

# 指定日志的级别
LOG_LEVEL = 'INFO'
LOG_FILE = 'log.txt'

十、scrapy的post请求

具体是写start_requests方法:def start_requests(self)

start_requests的返回值:

scrapy.FormRequest(url=url,headers=headers, callback=self.parse_item, formdata=data)

其中:

  • url:要发送的post地址
  • headers:可以定制头信息
  • callback:回调函数
  • formdata:post所携带的数据,这是一个字典

具体以百度翻译示例:

在创建项目之后,对start_requeats文件进行重新:

import scrapy
import jsonclass FanyiSpider(scrapy.Spider):name = "fanyi"allowed_domains = ["fanyi.baidu.com"]start_urls = ["https://fanyi.baidu.com/sug"]def start_requests(self):url = 'https://fanyi.baidu.com/sug'data = {'kw': 'hello'}yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse_second)def parse_second(self, response):# 解决编码问题print(json.loads(response.text))

运行发现毫无问题。

十一、scrapy的代理

在Scrapy中使用代理可以帮助你绕过一些反爬虫机制或避免IP被封禁。可以通过以下几种方式实现Scrapy的代理设置:

11.1、 settings.py 中配置代理

在Scrapy的 settings.py 中可以通过设置 HTTP_PROXYDOWNLOADER_MIDDLEWARES 来全局配置代理。例如:

# settings.py
HTTP_PROXY = 'http://your_proxy_ip:proxy_port'DOWNLOADER_MIDDLEWARES = {'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,'your_project.middlewares.CustomProxyMiddleware': 543,
}

HttpProxyMiddleware 是Scrapy自带的中间件,你可以通过设置 HTTP_PROXY 来为所有请求指定一个代理。

11.2、 自定义代理中间件

如果需要根据不同请求设置不同的代理,可以自定义一个代理中间件:

# middlewares.py
import randomclass CustomProxyMiddleware(object):def __init__(self):self.proxies = ['http://proxy1_ip:proxy1_port','http://proxy2_ip:proxy2_port','http://proxy3_ip:proxy3_port',]def process_request(self, request, spider):# 随机选择一个代理proxy = random.choice(self.proxies)request.meta['proxy'] = proxyspider.logger.info(f"Using proxy: {proxy}")

然后在 settings.py 中启用这个中间件:

# settings.py
DOWNLOADER_MIDDLEWARES = {'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,'your_project.middlewares.CustomProxyMiddleware': 543,
}
11.3、 为特定请求设置代理

如果你不想为所有请求都设置代理,可以在 spider 中为某些请求动态设置代理:

def start_requests(self):urls = ['http://example.com', 'http://another-site.com']for url in urls:request = scrapy.Request(url=url, callback=self.parse)request.meta['proxy'] = 'http://your_proxy_ip:proxy_port'yield request
11.4、 使用第三方代理服务

如果你需要大量代理,可能需要使用一些代理池或者代理服务。可以通过API获取代理,并在 middlewares.py 中根据实际需求动态设置代理。

class DynamicProxyMiddleware(object):def fetch_proxy(self):# 调用API获取代理response = requests.get('https://proxy-provider.com/api/get_proxy')return response.textdef process_request(self, request, spider):proxy = self.fetch_proxy()request.meta['proxy'] = proxyspider.logger.info(f"Using proxy: {proxy}")

通过这种方式,你可以动态地获取代理,并应用于请求。

这些方法可以灵活地帮助你在Scrapy中设置和管理代理,从而提高爬虫的成功率。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解equals底层原理

equals 方法是 Java 中用于比较两个对象是否“相等”的方法。在 Java 中&#xff0c;每个类都继承自 java.lang.Object 类&#xff0c;而 equals 方法正是定义在 Object 类中的一个方法。默认情况下&#xff0c;Object 类的 equals 方法比较的是两个对象的内存地址&#xff08;…

SQL 多表联查

SQL JOIN (w3school.com.cn) SQL join用于根据两个或多个表中的列之间的关系&#xff0c;从这些表中查询数据。 之前跟着老师学数据库的时候学过&#xff0c;最近又在比较频繁的使用&#xff0c;再复习一下。 Person表&#xff1a; Id_P &#xff1a;居民编号。主键 …

大数据开发基于Hadoop+springboot平台的岗位推荐系统

文章目录 前言项目介绍技术介绍功能介绍核心代码数据库参考 系统效果图文章目录 前言 文章底部名片&#xff0c;获取项目的完整演示视频&#xff0c;免费解答技术疑问 项目介绍 随着网络科学技术不断的发展和普及化&#xff0c;用户在寻找适合自己的信息管理系统时面临着越来…

成功解决pycharm软件中按住Ctrl+点击指定函数却不能跳转到对应库中的源代码

成功解决pycharm软件中按住Ctrl点击指定函数却不能跳转到对应库中的源代码 目录 解决问题 解决方法 解决问题 在pycharm软件中按住Ctrl点击指定函数却不能跳转到对应库中的源代码 解决方法

探索秘境:如何使用智能体插件打造专属的小众旅游助手『小众旅游探险家』

文章目录 摘要引言智能体介绍和亮点展示介绍亮点展示 已发布智能体运行效果智能体创意想法创意想法创意实现路径拆解 如何制作智能体可能会遇到的几个问题快速调优指南总结未来展望 摘要 本文将详细介绍如何使用智能体平台开发一款名为“小众旅游探险家”的旅游智能体。通过这…

个人健康系统|个人健康数据管理系统|基于小程序+java的个人健康数据管理系统设计与实现(源码+数据库+文档)

个人健康数据管理系统 目录 基于小程序java的个人健康数据管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师…

重构案例:将纯HTML/JS项目迁移到Webpack

我们已经了解了许多关于 Webpack 的知识&#xff0c;但要完全熟练掌握它并非易事。一个很好的学习方法是通过实际项目练习。当我们对 Webpack 的配置有了足够的理解后&#xff0c;就可以尝试重构一些项目。本次我选择了一个纯HTML/JS的PC项目进行重构&#xff0c;项目位于 GitH…

web3学习-区块链基础知识

1.1 区块链技术简史 block chain 点对点的分布式交易系统 比特币协议并不是图灵完备的。 以太坊协议加入了智能合约&#xff0c;智能合约是以太坊协议与比特币协议的最大区别&#xff08;图灵完备&#xff09; 1.2、区块链设计哲学 去中心化 由于没有中心化的数据库作为…

记录一个容易混淆的 Spring Boot 项目配置文件问题

记录一个容易混淆的 Spring Boot 项目配置文件问题 去年&#xff0c;我遇到了这样一个问题&#xff1a; 在这个例子中&#xff0c;由于密码 password 以 0 开头&#xff0c;当它被 Spring Boot 的 bean 读取时&#xff0c;前导的 0 被自动去掉了。这导致程序无法正确读取密码。…

网盘直链下载神器NDM

工具介绍 ​Neat Download Manager分享一款网盘不限速神器,安装步骤稍微有一点繁琐,但实际体验下载速度飞快,个人实际体验还是非常不错的 NDM是一款免费且强大的下载工具。可以帮助你下载各种文件&#xff0c;还能够在多任务下载中保持出色的速度及其稳定性 通过网盘分享的文…

【MySQL核心面试题】MySQL 核心 - Explain 执行计划详解!

欢迎关注公众号 【11来了】&#xff08;文章末尾即可扫码关注&#xff09; &#xff0c;持续 中间件源码、系统设计、面试进阶相关内容 在我后台回复 「资料」 可领取 编程高频电子书&#xff01; 在我后台回复「面试」可领取 30w 字的硬核面试笔记&#xff01; 感谢你的关注&…

MySQL【知识改变命运】10

联合查询 0.前言1.联合查询在MySQL里面的原理2.练习一个完整的联合查询2.1.构造练习案例数据2.2 案例&#xff1a;⼀个完整的联合查询的过程2.2.1. 确定参与查询的表&#xff0c;学⽣表和班级表2.2.2. 确定连接条件&#xff0c;student表中的class_id与class表中id列的值相等2.…

wordpress 子比主题美化 四宫格 多宫格 布局插件

wordpress 主题美化 四宫格 多宫格 布局插件&#xff08;只在子比主题上测试过&#xff0c;其它主题没测试&#xff09; A5资源网四宫格布局插件是一个功能丰富的WordPress插件,专为创建自适应的四宫格布局而设计。这个插件具有以下主要特点: 灵活的布局: 支持1到8个宫格的自定…

Springboot整合knife4j生成文档

前言 在开发过程中&#xff0c;接口文档是很重要的内容&#xff0c;用于前端对接口的联调&#xff0c;也用于给其他方使用。但是手写相对比较麻烦。 当然也有swagger之类的&#xff0c;但是界面没有那么友好。 官网&#xff1a; 整合步骤 整合依赖 需要根据版本进行&…

如何使用 pnpm 进行打补丁patch操作?推荐两个方法

前言 作为一个前端开发者&#xff0c;我们每天都在和各种各样的库和依赖打交道。node_modules 目录中存放着我们项目的各种依赖。我们有时需要对其中的一些依赖进行修改&#xff0c;比如修复某个 bug 或者增加某些自定义功能。这时候&#xff0c;给 node_modules 打补丁就显得…

为您的 WordPress 网站打造完美广告布局 A5广告单元格插件

一个为 WordPress 网站量身定制的强大工具,它将彻底改变您展示广告的方式 灵活多变的布局设计 A5 广告单元格插件的核心优势在于其无与伦比的灵活性。无论您是想要创建整齐的网格布局,还是希望打造独特的不规则设计,这款插件都能满足您的需求。 自定义网格数量&#xff1a;从 2…

androidStudio编译导致的同名.so文件冲突问题解决

files found with path lib/arm64-v8a/libserial_port.so from inputs: ...\build\intermediates\library_jni\debug\jni\arm64-v8a\libserial_port.so C:\Users\...\.gradle\caches\transforms-3\...\jni\arm64-v8a\XXX.so 解决方式如下&#xff1a; 1.将gradle缓存文件删…

TwinCAT3安装 Advanced Motion Pack库

文章目录 一.简介二.安装方式1. 下载地址2. 双击下载好的安装包3. 选择语言&#xff08;只有英文和德语&#xff09;4. 点击Next5. 选择Accept6. 填写公司和组织名称&#xff08;随意&#xff09;7. 点击Install8. 等待安装完成9. 点击Finish 一.简介 TF5420 TC3 Motion Pick-…

深度学习-1:逻辑回归和梯度下降

逻辑回归 逻辑回归是一个二分分类问题 比如判断一张图片中是否是猫就是一个二类分类问题 图像由像素值组成&#xff0c;要将图像输入模型&#xff0c;就将其变为一个向量&#xff0c;该向量存储三个通道上的所有像素值&#xff0c;若图像尺寸为64x64x3&#xff0c;则向量维度…

RequestBody接收参数报错com.fasterxml.jackson.databind.exc.MismatchedInputException

目录&#xff1a; 1、错误现象2、解决办法3、最终验证 1、错误现象 报错的现象和代码如下&#xff1a; 2、解决办法 查了很多都说参数类型对不上&#xff0c;但是明明是对上的&#xff0c;没有问题&#xff0c;最后只有换接收方式后验证是可以的&#xff1b;最终想了一下&…