1

简介

本人现在是一个学生,平时主要用的是Java,业余时间学习了Python,在提高自己的同时,想把自己学习过程记录下来,希望可以帮到更多入门的同学们。

所使用到的工具

  • PyCharm

  • Python3.6

  • Scrapy

创建一个scrapy项目

在你的工作目录的文件夹下打开命令提示符窗口,输入:

scrapy startproject demo

如果出现下面的提示,则说明创建成功。

图片描述

使用PyCharm打开这个scrapy项目,它的目录结构是这样的:

图片描述

  • scrapy.cfg文件中主要包含的是项目的相关设置。

  • demo文件夹下是用于编写爬虫的目录。

  • items.py:定义我们所要爬取的信息的相关属性。

  • middlewares.py:爬虫中间件,这里可以用过自定义相关的方法,用来处理爬虫的响应和请求。

  • pipelines.py:当数据被爬虫爬取下来后,它会被发送到item pipelines中,每个item pipelines组件(有时称为“项目管道”)是一个实现简单方法的Python类。他们收到一个项目并对其执行操作,还决定该项目是否应该继续通过管道或被丢弃并且不再被处理。

  • settings.py:项目的设置文件。

编写代码

在spiders文件夹下创建douban_spider.py文件
图片描述

这是一个空的.py文件,然后在这编写爬虫代码。

# 爬虫类需要继承scrapy下的Spider类。
import scrapy

class douban_movie_spider(scrapy.Spider):
    # 项目的启动名
    name = "douban_movie"
    # 如果网站设置有防爬措施,需要添加上请求头信息,不然会爬取不到任何数据
    headler = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 '
                      'Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
    }
    # 开始链接
    start_urls = [
        'https://movie.douban.com/top250'
    ]
    # start_requests方法为scrapy的方法,我们对它进行重写。
    def start_requests(self):
       # 将start_url中的链接通过for循环进行遍历。
       for url in self.start_urls:
             # 通过yield发送Request请求。
               # 这里的Reques注意是scrapy下的Request类。注意不到导错类了。
            # 这里的有3个参数:
            #        1、url为遍历后的链接
            #        2、callback为发送完请求后通过什么方法进行处理,这里通过parse方法进行处理。
            #        3、如果网站设置了防爬措施,需要加上headers伪装浏览器发送请求。
            
           yield scrapy.Request(url=url, callback=self.parse, headers=self.headler)

    # 重写parse对start_request()请求到的数据进行处理
    def parse(self, response):
       pass
        

页面分析

打开https://movie.douban.com/top250,点击f12开发者工具。

图片描述

使用选取工具选取整个电影的信息,可以发现,所有的信息都是放在单独的一个li标签中的,而且在li下还有一个class为item的div包裹着所有的信息。

图片描述

parse方法

def parse(self, response):
    # 这里使用scrapy的css选择器,既然数据在class为item的div下,那么把选取范围定位div.item
    for quote in response.css('div.item'):
        # 通过yield对网页数据进行循环抓取,我们要抓取的内容有3个,分别如下
        yield {
            "电影名": quote.css('div.info div.hd a span.title::text').extract_first(),
            "评分":quote.css('div.info div.bd div.star span.rating_num::text').extract(),
            "引言": quote.css('div.info div.bd p.quote span.inq::text').extract()
        }

写完上面的代码,其实只是抓取一页的罢了,为了抓取完整的top250榜单,我们需要让爬虫跳转到下一页再进行循环抓取,因为每个页面的结构是一样的,所以不用担心会抓取不到。

图片描述

next_url=response.css('div.paginator span.next a::attr(href)').extract()

然后,需要对next_url进行判断是否存在,然后再次发送Request请求。这样爬虫就会在爬完一个页面后点击下一页再继续爬去,往复循环,直到爬取完毕。

if next_url:
    next_url="https://movie.douban.com/top250"+next_url[0]
    print(next_url)
    yield scrapy.Request(next_url,headers=self.headler)

那么到这里,代码就写完了。

然后我们来运行一下这个爬虫,scrapy框架是通过命令来启动爬虫的,

在项目根目录下打开命令提示符,输入:

   
scrapy crawl douban_movie -o douban_movice.csv

scrapy会把爬取到的结果保存到douban_movice.csv这个文件里。

爬虫运行后,就会输出大量的日志信息和爬去的网页的内容。
图片描述

数据会保存在douban_movice.csv这个文件中。

图片描述

但是,有个问题,如果爬虫报错了怎么办?

因为使用命令启动的爬虫,所以爬虫的日志信息都是显示在cmd中的,这样日志信息阅读起来非常的不友好。所以我们需要写一个启动爬虫的python脚本,这样日志信息就会输出在python环境下了

新建一个run.py文件,代码如下:

from scrapy import cmdline

name='douban_movie -o douban.csv'
cmd = 'scrapy crawl {0}'.format(name)
cmdline.execute(cmd.split())

然后运行这个文件,所以的日志信息就输出在Python环境下,便于调试。
图片描述

运行得到的结果都是一样的。

完整的代码是这样的:

import scrapy

class douban_movie_spider(scrapy.Spider):
    name = "douban_movie"

    headler = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 '
                      'Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
    }

    start_urls = [
        'https://movie.douban.com/top250'
    ]


    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url=url, callback=self.parse, headers=self.headler)

    def parse(self, response):
        for quote in response.css('div.item'):
            yield {
                "电影名": quote.css('div.info div.hd a span.title::text').extract_first(),
                "评分":quote.css('div.info div.bd div.star span.rating_num::text').extract(),
                "引言": quote.css('div.info div.bd p.quote span.inq::text').extract()
            }
        next_url=response.css('div.paginator span.next a::attr(href)').extract()
        if next_url:
            next_url="https://movie.douban.com/top250"+next_url[0]
            print(next_url)
            yield scrapy.Request(next_url,headers=self.headler)

好了,本教程到此结束。


凉皮
74 声望9 粉丝

引用和评论

0 条评论