首页 > 其他分享 >Scrapy

Scrapy

时间:2024-02-13 18:00:31浏览次数:26  
标签:douban title movie self scrapy item Scrapy

1、安装scrapy

win7下conda安装scrapy
conda search scrapy
conda install scray=2.8.0
将C:\Program Files\Anaconda3\envs\my_env3.8\Scripts加入环境变量
这样cmd中就可以使用scrapy命令
cmd需要重启。

性能相关及Scrapy笔记-博客园 武沛齐

2、Scrapy项目配置

  1. 要爬取网站使用的可信任证书(默认支持):
    setting.py中加入
DOWNLOADER_HTTPCLIENTFACTORY = "scrapy.core.downloader.webclient.ScrapyHTTPClientFactory"
DOWNLOADER_CLIENTCONTEXTFACTORY = "scrapy.core.downloader.contextfactory.ScrapyClientContextFactory"
  1. 运行:
    出现2023-12-12 20:40:05 [scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt: <GET https://space.bilibili.com/3493119047764705/video>
    爬虫出现Forbidden by robots.txt
    在setting改变ROBOTSTXT_OBEY为False,让scrapy不要遵守robot协议,之后就能正常爬取了。
    ROBOTSTXT_OBEY = False

  2. scrapy抓取豆瓣报出403错误?
    在setting.py中设置USER_AGENT 伪装成浏览器即可
    USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'

3、第一个scrapy应用

douban.py

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

    def parse(self, response):
        sel = Selector(response)
        list_items = sel.css('#content > div > div.article > ol > li')
        for item in list_items:
            movie_item = MovieItem()
            movie_item['title'] = item.css('span.title::text').extract_first()
            movie_item['rating_num'] = item.css('span.rating_num::text').extract_first()
            movie_item['subject'] = item.css('span.inq::text').extract_first()
            yield movie_item

items.py

import scrapy

class MovieItem(scrapy.Item):
    title = scrapy.Field()
    rating_num = scrapy.Field()
    subject = scrapy.Field()

运行 scrapy crawl douban -o douban.csv
将数据输出到douban.csv文件

4、爬取多页

import scrapy
from scrapy import Selector, Request
from scrapy.http import HtmlResponse
from Test1.items import MovieItem

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

    def parse(self, response: HtmlResponse):
        sel = Selector(response)
        list_items = sel.css('#content > div > div.article > ol > li')
        for item in list_items:
            movie_item = MovieItem()
            movie_item['title'] = item.css('span.title::text').extract_first()
            movie_item['rating_num'] = item.css('span.rating_num::text').extract_first()
            movie_item['subject'] = item.css('span.inq::text').extract_first()
            yield movie_item
        # print(response.text)

        hrefs_list = sel.css('div.paginator > a::attr(href)')
        for href in hrefs_list:
            url_parms = href.extract()
            url = response.urljoin(url_parms)
            yield Request(url=url)

这里有个bug:
爬第2页时,还会取到第一页的url:“https://movie.douban.com/top250?start=0&filter=” 再爬一次第一页,由于第一次爬第一页是https://movie.douban.com, 所以scrapy无法去重。
解决办法1: start_urls = ["https://movie.douban.com/top250?start=0&filter="]

解决办法2(推荐):不解析页码url,直接构造start_requests

...
class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com"]
    # start_urls = ["https://movie.douban.com/top250?start=0&filter="]

    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):
        ...

6、将数据写入Excel:

安装openpyxl:pip install openpyxl
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

class Test1Pipeline:

    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')

    def process_item(self, item, spider):
        title = item.get('title', '')
        ratting = item.get('rating_num') or ''
        sb = item.get('subject', '')
        self.ws.append((title, ratting, sb))
        return item  # return了,终端就会打印

setting.py中,将管道配置取消注释。300是优先级,数字越小,越先执行。

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   "Test1.pipelines.Test1Pipeline": 300,
}

7、将数据写入MySQL

创建数据库:CREATE DATABASE Test1Spider
使用数据库:use test1spider
删除表:DROP TABLE 语句用于删除数据库中的现有表:

-- 删除表,如果存在的话
DROP TABLE IF EXISTS mytable;

-- 直接删除表,不检查是否存在
DROP TABLE mytable;

创建数据表:(其中需要注意:每字段前不是tab,而是两个空格)

CREATE TABLE IF NOT EXISTS `tb_top_movie`(
  `mov_id` INT UNSIGNED AUTO_INCREMENT comment '编号',
  `title` varchar(50) NOT NULL comment '标题',
  `rating` decimal(3,1) NOT NULL comment '评分',
  `subject` varchar(200) default '' comment '主题',
  PRIMARY KEY (`mov_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 comment='Top电影表';

完美解决 ERROR 1064 (42000): You have an error in your SQL syntax

pipelines.py

import pymysql

class DbPipeline:
    def __init__(self):
        self.conn = pymysql.connect(host='localhost',
                                    port=3306,
                                    user='root',
                                    password='123456',
                                    database='test1spider',
                                    charset='utf8mb4')
        self.cursor = self.conn.cursor()

    def close_spider(self, spider):
        self.conn.commit()
        self.conn.close()

    def process_item(self, item, spider):
        title = item.get('title', '')
        rating = item.get('rating_num') or 0
        sb = item.get('subject', '')
        self.cursor.execute(
            'insert into tb_top_movie (title, rating, subject) values (%s, %s, %s)',
            (title, rating, sb)
        )
        return item 

批处理:

import pymysql

class DbPipeline:
    def __init__(self):
        self.conn = pymysql.connect(host='localhost',
                                    port=3306,
                                    user='root',
                                    password='123456',
                                    database='test1spider',
                                    charset='utf8mb4')
        self.cursor = self.conn.cursor()
        self.data = []

    def close_spider(self, spider):
        if len(self.data) > 0:
            self._write_to_db()
        self.conn.close()

    def process_item(self, item, spider):
        title = item.get('title', '')
        rating = item.get('rating_num') or 0
        sb = item.get('subject', '')
        self.data.append((title, rating, sb))
        if len(self.data) == 100:
            self._write_to_db()
        return item  # return了,下一个pipeline才能拿到item继续处理

    def _write_to_db(self):
        self.cursor.executemany(
            'insert into tb_top_movie (title, rating, subject) values (%s, %s, %s)',
            self.data
        )
        self.conn.commit()
        self.data.clear()

MySQL 查看表结构简单命令

8、其它

class TestSpider(scrapy.Spider):
    ...
	def parse(self, response: HtmlResponse): # 这时,pycharm会有警告:由于这个是重写父类方法,但它没有与父类方法保持一致
        ...

解决:
class TestSpider(scrapy.Spider):
    ...
	def parse(self, response: HtmlResponse, **kwargs): # 父类方法有**kwargs参数
        ...

标签:douban,title,movie,self,scrapy,item,Scrapy
From: https://www.cnblogs.com/zhlforhe/p/18014682

相关文章

  • 第 7章 Python 爬虫框架 Scrapy(上)
    第7章Python爬虫框架Scrapy(上)编写爬虫可以看成行军打仗,基本的角色有两个:士兵和将军,士兵冲锋陷阵,而将军更多地是调兵遣将。框架就像一个将军,里面包含了爬虫的全部流程、异常处理和任务调度等。除了可以让我们少写一些烦琐的代码,学习框架还可以学到编程思想和提升编程能力。Pyt......
  • scrapy 响应文本乱码(不支持Brotli解压)
    一.介绍在scrapy中,默认不支持Brotli解压,当发现响应乱码时,如何分析确定是由Brotli压缩引起的呢?1)是看请求头是否有'Accept-Encoding':"gzip,deflate,br"中的br,如果去掉br再请求网页,如果响应不成功,则表示服务端只支持br压缩格式,如果成功则看是否乱码。2)......
  • Scrapy爬虫框架
    网络爬虫框架:ScrapyScrapy是一个非常优秀的爬虫框架,通过Scrapy框架,可以非常轻松的实现强大的爬虫系统。一、Scrapy简介Scrapy主要包括如下6个部分:ScrapyEngine:用来处理整个系统的数据流,触发各种事件。Scheduler:从URL队列中取出一个URL。Downloader:从internet上下载web资源......
  • 从python 单机版爬虫 scrapy 到 分布式scrapy-redis 爬虫用最简单的步骤创建实例
    scrapy是很强大的模块化爬虫框架,具有很高的灵活性,使用频率很高,使用该框架能大大提高开发效率,scrapy-redis是在scrapy框架开发了组件,替换队列部分,实现多台服务器并行运行爬虫,提高爬取速度。下面是用最简单的例子从建立普通scrapy爬虫,然后数据保存mysql,最后简单替换几行就能使用s......
  • Scrapy部署相关
    安装scrapyd服务pipinstallscrapyd-ihttps://pypi.tuna.tsinghua.edu.cn/simple官方文档安装pipinstallscrapyd-client官方文档scrapy-deploy部署建setup.pyfromsetuptoolsimportsetup,find_packagessetup(name='project',version='1.0'......
  • scrapy中运行一段时间报错pymysql.err.InterfaceError: (0, '')
    错误信息Traceback(mostrecentcalllast):File"/home/anaconda3/envs/python36/lib/python3.6/site-packages/twisted/python/threadpool.py",line250,ininContextresult=inContext.theWork()File"/home/anaconda3/envs/python36/lib/p......
  • Scrapy爬网站数据,存到MySQL
    一、框架简介1.1、简介  Scrapy框架是用纯Python实现的一个为了爬取网站数据、提取结构性数据而编写的可扩展的开源应用框架,只需要少量代码就能够快速地实现数据爬取。往往手写一个爬虫需要进行发送网络请求、数据解析、数据存储、反反扒机制、异步请求等步骤,如果都从零开始......
  • Scrapy框架与数据库整合:如何实现动态数据存储?
    随着互联网数据量的不断增加,如何快速、准确地爬取、处理、存储数据成为了互联网应用开发的关键问题。而Scrapy框架作为一个高效的爬虫框架,凭借其灵活、高速的爬取方式被广泛应用于各种数据爬取场景。然而,仅仅将爬取到的数据保存到文件中,无法满足大部分应用程序的需要。因为在当前......
  • 【Python爬虫】Scrapy框架处理分页爬取+cookie登录_17k小说网
    简介本文主要讲常规分页爬取与利用Scrapy框架怎么快捷的爬取分页的数据以及cookie登录,案例网站时17k小说网,url是https://www.17k.com/常规分页爬取Scrapy框架分页爬取cookie登录分页常规分页爬取常规分页爬取,直接观察页面数据,一共有多少页数据,就for循环多少次classXiao......
  • 【Python爬虫】Scrapy框架图片下载_桌面壁纸ZOL(纯案例)
    Spider代码classBizhizolSpider(scrapy.Spider):name="bizhizol"allowed_domains=["zol.com.cn"]start_urls=["https://desk.zol.com.cn/youxi/"]defparse(self,response,**kwargs):#print(response.te......