Python最火爬虫框架Scrapy入门与实践,豆瓣电影 Top 250 数据采集

时间:2022-07-22
本文章向大家介绍Python最火爬虫框架Scrapy入门与实践,豆瓣电影 Top 250 数据采集,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Python爬虫框架Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

scrapy安装

Linux:

pip3 install scrapy

Windows:

a.

pip3 install wheel

b. 下载twisted

http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

c. 进入下载目录,

执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl

d. pip3 install pywin32

e. pip3 install scrapy

强调:

如果windows10安装

pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl失败,

请自行换成32位的即可解决!!!

提示:如果在pycharm中安装scrapy失败

两种解决办法:

1、把pycharm中的虚拟环境模式改成直接指向现在的python安装环境!

2、把python环境中的scrapy,twisted等直接复制到pycharm工程所在的虚拟环境中去!

Scrapy组件:

引擎(Scrapy)

用来处理整个系统的数据流处理, 触发事务(框架核心)

调度器(Scheduler)

用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址

下载器(Downloader)

用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)

爬虫(Spiders)

爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面

项目管道(Pipeline) 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

下载器中间件(Downloader Middlewares)

位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。

爬虫中间件(Spider Middlewares)

介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。

调度中间件(Scheduler Middewares)

介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。

Scrapy运行流程

Scrapy运行流程大概如下:

引擎从调度器中取出一个链接(URL)用于接下来的抓取

引擎把URL封装成一个请求(Request)传给下载器

下载器把资源下载下来,并封装成应答包(Response)

爬虫解析Response

解析出实体(Item),则交给实体管道进行进一步的处理

解析出的是链接(URL),则把URL交给调度器等待抓取

* 解释:引擎首先会将爬虫文件中的起始url获取,并且提交到调度器中。如果需要从url中下载数据,则调度器会将url通过引擎提交给下载器,下载器根据url去下载指定内容(响应体)。下载好的数据会通过引擎移交给爬虫文件,爬虫文件可以将下载的数据进行指定格式的解析。如果解析出的数据需要进行持久化存储,则爬虫文件会将解析好的数据通过引擎移交给管道进行持久化存储。

爬取目标网址:

https://movie.douban.com/top250

第一步:创建 Scrapy 项目

scrapy startproject douban

由于这里使用的是pycham ide,创建运行调试文件

pycham ide调试文件代码

新建py文件 entrypoint.py

from scrapy.cmdline import execute
execute(['scrapy','crawl','douban'])

注意:douban 是 Scrapy项目名

第二步:设置字段

items.py

引入 scrapy框架

设置字段格式:字段名=scrapy.Field()

import scrapy
 
class DoubanItem(scrapy.Item):
    num=scrapy.Field() #序列号
    name=scrapy.Field() #电影名
    introduce=scrapy.Field() #介绍
    star=scrapy.Field() # 星级评分
    appraise=scrapy.Field() # 评价人数
    survey=scrapy.Field() #一句话介绍

第三步:相关设置修改

settings.py

1.开启协议头

爬取豆瓣网站,需要开启协议头

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)'

2.抓取调试开启

# Enable and configure HTTP caching (disabled by default)
# See [url=https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings]https://docs.scrapy.org/en/lates ... middleware-settings[/url]
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'

这里开启的含义: 这几行注释的作用是,Scrapy会缓存你有的Requests!当你再次请求时,如果存在缓存文档则返回缓存文档,而不是去网站请求,这样既加快了本地调试速度,也减轻了 网站的压力。

3.激活item pipeline

我们的pipeline定义后,需要在配置文件中添加激活才能使用,因此我们需要配置settings.py。

ITEM_PIPELINES = {
    'douban.pipelines.DoubanPipeline': 300,
}

注意,这里不开启,存储不了数据!

第四步:爬虫文件的编写,关键!

doub.py

版本一:

# -*- coding: utf-8 -*-
import scrapy
import requests
from douban.items import DoubanItem
from bs4 import BeautifulSoup
from scrapy.http import Request

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


    def parse(self, response):
        item_list=response.xpath('//ol[@class="grid_view"]/li')
        for item in item_list:
            douban_item=DoubanItem()
            douban_item['num'] = item.xpath('.//div[@class="pic"]/em/text()').extract_first()
            douban_item['name']=item.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first()
            #print(douban_item['name'])
            introduces=item.xpath('.//div[@class="bd"]/p[1]/text()').extract()
            for introduce in introduces:
                introduce_date="".join(introduce.split())
                douban_item['introduce']=introduce_date
                #print(douban_item['introduce'])
            douban_item['star']=item.xpath('.//div[@class="star"]/span[@class="rating_num"]/text()').extract_first()
            #print(douban_item['star'])
            douban_item['appraise'] = item.xpath('.//div[@class="star"]/span[4]/text()').extract_first()
            douban_item['survey']=item.xpath('.//p[@class="quote"]/span[@class="inq"]/text()').extract_first()
            #print(douban_item['survey'])
            print(douban_item)
            yield douban_item
        next_page=response.xpath('//div[@class="paginator"]/span[@class="next"]/a/@href').extract()
        if next_page:
            yield Request(f'https://movie.douban.com/top250{next_page[0]}',callback=self.parse)

版本二:

def parse(self, response):
    paginator_urls=[]
    paginator_urls.extend(self.start_urls)
    paginators=BeautifulSoup(response.text,'lxml').find('div',class_="paginator").find_all('a')[:-1]
    for paginator in paginators:
        paginator=f"https://movie.douban.com/top250{paginator['href']}"
        paginator_urls.append(paginator)
    print(paginator_urls)
    paginator_urls=set(paginator_urls)
    for paginator_url in paginator_urls:
        print(paginator_url)
        yield Request(paginator_url,callback=self.get_content)

def get_content(self,response):
    thispage=BeautifulSoup(response.text,'lxml').find('span',class_="thispage").get_text()
    print(thispage)

Scrapy自带xpath 与爬虫 etree xpath类似 注意.extract() 和.extract_first()

在使用scrapy爬虫的时候,我们常常使用xpath来获取html标签,但是我们经常会用到提取的方法

有两种提取的方法

分别是:

extract():

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

extract_first():

这个方法返回的是一个string字符串,是list数组里面的第一个字符串。

Xpath选择器:

response.selector属性返回内容相当于response的body构造了一个Selector对象。

Selector对象可以调用xpath()方法实现信息的解析提取。

在xpath()后使用extract()可以返回所有的元素结果。

若xpath()有问题,那么extract()会返回一个空列表。

在xpath()后使用extract_first()可以返回第一个元素结果。

for v in dllist:
     print(v.xpath("./dt/text()").extract_first())
     print("="*50)
     alist = v.xpath(".//a")
     for a in alist:
             print(a.xpath("./@href").extract_first(),end=":")
             print(a.xpath("./span/img/@alt").extract_first())
             
#来源:CSDN博主「周雄伟」

版本二为调用bs4抓取数据

但是代码、排序等等不完美,推荐版本一!

第五步:保存数据,写入本地数据库

pipelines.py

import pymysql
 
class DoubanPipeline(object):
    def __init__(self):
        #连接MySQL数据库
        self.connect=pymysql.connect(
            host="localhost",
            user="root",
            password="123456",
            db="xiaoshuo",
            port=3306,
        )
        self.cursor=self.connect.cursor()
    def process_item(self, item, spider):
        self.cursor.execute('insert into movie(num,name,introduce,star,appraise,survey)VALUES("{}","{}","{}","{}","{}","{}")'.format(item['num'],item['name'],item['introduce'],item['star'],item['appraise'],item['survey']))
        self.connect.commit()
        return item
 
    #关闭数据库
    def close_spider(self,spider):
        self.cursor.close()

项目:

数据:

运行效果:

scrapy数据保存为 csv 方法:

在Scrapy中,负责导出数据的组件被称为Exporter,Scrapy内部实现了多个Exporter,每个Exporter实现一种数据格式的导出,

支持的格式如下:

JSON(JsonItemExporter)

JSON lines(JsonLinesItemExporter)

CSV(CsvItemExporter)

XML(XmlItemExporter)

Pickle(PickleItemExporter)

Marshal(MarshalItemExporter)

cmd命令方法

1.cd进入项目文件

2.敲入命令

scrapy crawl douban -o douban.csv

由于未指定编码,所以导致保存输出文件为乱码

指定一下 utf-8 编码 格式

scrapy crawl douban -o douban.csv -s FEED_EXPORT_ENCIDING=utf-8

或者

使用第三方软件修改编码格式,notepad2打开,选择编码ANSI,保存,再用excel打开就是正常的了!

最后的解决办法

在创建项目的settings.py中,添加如下代码

FEED_EXPORT_ENCODING = 'gb18030'

即可解决乱码问题。

第六步:代{过}{滤}理ip的使用

由于没有账号,未测试。。

项目打包

链接:

https://pan.baidu.com/s/1GX9srMbh7aJbbpC8y6ZzDw

提取码:

zp3h