python爬虫入门看这个就够了python 入门@IT·互联网

Scrapy爬取豆瓣电影Top250

2017-11-07  本文已影响338人  Treehl

这两天摸索了下scrapy,刚看文档的时候觉得有点生无可恋,scrapy框架个人还是觉得比较难懂的,需要学习的地方非常多,之前用beautifulsoup4爬过top250,比scrapy简单更容易理解!!

Scrapy简介

Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。 下面对每个组件都做了简单介绍,数据流如下所描述。


image

引擎打开一个网站(open a domain),找到处理该网站的Spider并向该spider请求第一个要爬取的 URL(s)。
引擎从Spider中获取到第一个要爬取的URL并在调度器(Scheduler)以Request调度。
引擎向调度器请求下一个要爬取的URL。
调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求(request)方向)转发给下载 器(Downloader)。
一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方 向)发送给引擎。
引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。
Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。
引擎将(Spider返回的)爬取到的Item给Item Pipeline,将(Spider返回的)Request给调度器。
(从第二步)重复直到调度器中没有更多地request,引擎关闭该网站

scrapy的流程如图,并且可归纳如下

建议大家参考下中文版的Scrapy文档,看文档还是比较枯燥的,Scrapy又比较难懂(大神忽略),务必要有耐心!!!!!!

实战应用

首先下载Scrapy包

pip install scrapy

这样安装,windows平台应该是会报错的,我当时装Scrapy时废了很大劲才弄完。安装过程中Pycharm或者官网上找不到的模块可以上这个网址找Unofficial Windows Binaries for Python Extension Packages
Pywin32

接着,我们打开CMD,新建一个爬虫文件

scrapy startproject douban

image

C:\Users\ssaw\douban>tree /f
C:.
│ scrapy.cfg

└─douban
│ items.py
│ middlewares.py
│ pipelines.py
│ settings.py
init.py

└─spiders
init.py

简单介绍下这些文件

编辑items.py文件

# -*- coding: utf-8 -*-

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

import scrapy


class DoubanItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    movie_name = scrapy.Field()
    movie_star = scrapy.Field()
    movie_quote = scrapy.Field()

现在,我们在spiders文件夹下创建douban_spider.py
在我们编写爬虫之前,先了解一下scrapy的爬取机制,scrapy提取数据有自己的一套机制。它们被称作选择器(seletors),因为他们通过特定的 XPath 或者 CSS 表达式来“选择” HTML文件中的某个部分。
之前我在博客上也总结过一篇使用Xpath模拟登陆GitHub有兴趣可以看一下
附上Xpath学习教程Xpath

获取网页数据

打开Chrome(F12),查找元素
豆瓣电影TOP250

image
红框圈出来的分别代表

movie_name = div[@class="hd"]/a/span/
movie_star = div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]
movie_quote = div[@class="bd"]/p[@class="quote"]/span[@class="inq"]

# _*_ coding=utf-8 _*_

from scrapy.spiders import Spider
from scrapy.selector import Selector

class DouBanSpider(Spider):
    name = 'db'
    start_urls = ['https://movie.douban.com/top250']

    def parse(self, response):
        # print(response.body)
        selector = Selector(response)

        # print(selector)
        movies = selector.xpath('//div[@class="info"]')
        for movie in movies:
            movie_name = movie.xpath('div[@class="hd"]/a/span/text()').extract()
            movie_star = movie.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract()
            movie_quote = movie.xpath('div[@class="bd"]/p[@class="quote"]/span[@class="inq"]/text()').extract()


            print(movie_name)
            print(movie_star)
            print(movie_quote)

我们打开setting.py,加上U-A

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'

在CMD中输入scrapy crawl db,运行如下:


image

我们还可以在douban文件根目录创建一个main.py,这样就可以在Pycharm中运行了

from scrapy import cmdline
cmdline.execute("scrapy crawl db".split())

使用Item

Item对象是自定义的python字典。 您可以使用标准的字典语法来获取到其每个字段的值。(字段即是我们之前用Field赋值的属性),Spider将会将爬取到的数据以 Item 对象返回。

item = DoubanItem()

item['movie_name'] = movie_name
item['movie_star'] = movie_star
item['movie_quote'] = movie_quote

好了,现在我们先试着爬取单页面,查看下结果后,再去爬取多页面

from scrapy.spiders import Spider
from scrapy.selector import Selector
from douban.items import DoubanItem



class DouBanSpider(Spider):
    name = 'db'
    start_urls = ['https://movie.douban.com/top250']

    def parse(self, response):
        # print(response.body)
        selector = Selector(response)

        # print(selector)
        movies = selector.xpath('//div[@class="info"]')
        for movie in movies:
            movie_name = movie.xpath('div[@class="hd"]/a/span/text()').extract()
            movie_star = movie.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract()
            movie_quote = movie.xpath('div[@class="bd"]/p[@class="quote"]/span[@class="inq"]/text()').extract()

            #print(movie_name)
            #print(movie_star)
            #print(movie_quote)

            item = DoubanItem()

            item['movie_name'] = movie_name
            item['movie_star'] = movie_star
            item['movie_quote'] = movie_quote
            yield item
            print(movie_name)
            print(movie_star)
            print(movie_quote)
  1. name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字
  2. start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一, 后续的URL则从初始的URL获取到的数据中提取。
  3. parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象
#看一个yield函数的示例
#函数在每次循环时都会产生一个值,之后将其返回给它的调用者
#函数不断的生成数字的平方

def gensquares(N):
    for i in range(N):
        yield i ** 2
        
for i in gensquares(5):
    print(i, end=' ')

0 1 4 9 16 

好了,spider暂时写完了,我们试着运行下

scrapy crawl db -o douban.json -t json

-o 后面是导出文件名,-t 后面是导出类型。
然后来看一下导出的结果,Pycharm打开json文件即可


image

打印出来的内容需要编码
我们换种方式,把文件格式保存为CSV,使用EXCEL打开

scrapy crawl db -o douban.csv -t csv

image

用excel打开后假如是一堆乱码,就使用记事本打开,把它“另存为”时,编码选择ANSI


image

好了,现在我们添加多页面链接,完整地把TOP250爬取下来
我们从Elements中找到翻页lianjie


image
next_page =response.selector.xpath('//span[@class="next"]/link/@href').extract()
if next_page:
    next_page = next_page[0]
    print(next_page)
    yield Request(self.url + next_page, callback=self.parse)

CMD输入scrapy crawl db -o douban.csv -t csv ,开始运行


image

学习Scrapy需要反复查看文档、资料,这是个简单的学习总结,这两天准备再去学习MongoDB数据库,大家一起加油!!

参考链接
参考链接
Scrapy文档
GitHub
简书
最后,欢迎大家访问我的博客Treehl的博客

上一篇 下一篇

猜你喜欢

热点阅读