python爬虫框架scrapy 豆瓣实战

Scrapy

官方介绍是html

An open source and collaborative framework for extracting the data you need from websites.node

In a fast, simple, yet extensible way.python

意思就是web

一个开源和协做框架,用于以快速,简单,可扩展的方式从网站中提取所需的数据。sql


 

环境准备

本文项目使用环境及工具以下mongodb

  • python3
  • scrapy
  • mongodb

python3 scrapy的安装就再也不叙述chrome

mongodb是用来存储数据的nosql非关系型数据库 官方下载地址https://www.mongodb.com/download-center/community?jmp=docs数据库

mongodb图形化管理工具推荐使用nosqlmanagerjson


 项目建立

没错,咱们仍是挑软柿子捏,就爬取最简单的豆瓣电影top250api

😂这个网站几乎是每一个学习爬虫的人都会去爬取的网站,这个网站特别有表明性 话很少说,项目开始

建立scrapy项目须要在命令行中进行

切换到工做目录,而后输入指令  scrapy startproject douban

即建立成功,而后使用pycharm打开项目 首先看下目录结构

咱们发现项目spiders中只有一个文件,放爬虫的地方怎么会只有一个__init__.py呢 

别急咱们还须要输入一个命令来建立基本爬虫  打开cmd切换到目录文件夹下的spiders目录

输入 scrapy genspider douban_spider https://movie.douban.com/top250

以下图建立爬虫成功  

而后咱们打开项目分析目录结构

douban                                                      项目文件夹

  spiders                爬虫文件夹

    __init__.py

    douban_spider.py       爬虫文件

  __init__.py

  ietms.py              定义items数据结构的地方(即咱们爬取内容的属性之类的信息)

  middlewares.py          中间件

  pipelines.py           定义对于items的处理方法(数据清洗等)(须要在settings中开启pipelines选项)

  settings.py            项目的设置文件,定义全局的各类设置(好比头部代理,任务并发量,下载延迟等等)

scrapy.cfg                                                 项目的配置文件(包含一些默认的配置信息)

至此咱们的的项目算是建立成功了


 

肯定内容

建立好项目以后下一步就是肯定咱们要爬取的内容了,而后才能够开始编写咱们的items.py文件

首先打开目标网页进行分析 

网页中有哪些东西是咱们须要的呢?

  • 电影排名编号
  • 电影名称
  • 电影演职员以及年份分类
  • 电影星级评分 
  • 评论人数
  • 电影简介 

如今就能够根据内容来编写items.py文件了

items.py文件代码编写以下

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

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

import scrapy


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

    serial_number = scrapy.Field()#排名
    movie_name = scrapy.Field()#电影名称
    introduce = scrapy.Field()#电影简介基本信息
    star = scrapy.Field()#电影星级评分
    evaluate = scrapy.Field()#电影评论人数
    describe = scrapy.Field()#电影内容简介

 


 

内容提取spider文件编写

肯定内容以后就是很是关键的spider爬虫文件编写了 

测试阶段douban_spider.py文件编写以下:

# -*- coding: utf-8 -*-
import scrapy


class DoubanSpiderSpider(scrapy.Spider):
    #爬虫名字
    name = 'douban_spider'
    #容许的域名 爬取url都属于这个域名
    allowed_domains = ['movie.douban.com']
    #起始url
    start_urls = ['https://movie.douban.com/top250/']

    def parse(self, response):
        print(response.text)#打印响应内容
        pass

而后咱们须要运行下咱们的爬虫看下如今可否出什么信息

打开命令窗口并cd到项目目录下输入命令   scrapy crawl douban_spider

douban_spider是爬虫的名字

运行以下图

发现里面有爬虫的信息也有返回响应的信息,可是咱们能够看出来没有咱们想要的电影信息,如今怎么办?

稍微学习过爬虫的同窗都知道,爬虫是须要修改 USER_AGENT 的,这也是最简单的反爬虫机制,因此咱们一样须要去修改咱们爬虫的用户代理

去哪找头部代理呢?简单一点的能够直接去百度搜索一个,或者呢咱们用浏览器调试台把本身的用户代理复制下来

例如chrome浏览器按F12点击一个资源复制出来用户代理便可再也不赘述

打开settings.py文件  找到USER_AGENT修改以下:

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'douban (+http://www.yourdomain.com)'
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'

而后咱们再次打开命令窗口并cd到项目目录下输入命令   scrapy crawl douban_spider

发现已经有了咱们想要的电影信息

同时每次在命令行运行spider确实不方便,咱们能够在项目中添加一个main.py的启动文件以下

main.py编写代码:

from scrapy import cmdline
cmdline.execute('scrapy crawl douban_spider'.split())

运行,发现就获得了与命令行运行同样的效果了

接下来的工做就是数据处理了,提取出咱们想要的信息  继续编写spider.py文件

对于数据的提取咱们使用xpath定位 先来观察目标网站的元素 咱们能够看到top250电影中每一页有25个电影信息 而且每一个电影信息都是一个列表 li

xpath有好多种写法 咱们能够审查元素而后编写xpath定位,或者呢直接用chrome也能够直接获取某元素的xpath路径

例如使用某xpath浏览器插件来找咱们须要的元素 咱们首先先找到每一个电影的定位

如图咱们编写 //ol[@class='grid_view']/li/div[@class='item'] 就能够定位到当前每一个电影 其实咱们简单点直接写 //ol/li 也能够,可是咱们最好直接精确一点 xpath语法以下

表达式 描述
nodename 选取此节点的全部子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

而后同理,咱们就能够找到电影排名,名称,评论等等信息的xpath, 接下来在spider.py文件中引用咱们的 items.py中编写的DoubanItem类 而后完成对象属性的赋值

spider.py文件代码:

# -*- coding: utf-8 -*-
import scrapy
from douban.items import DoubanItem


class DoubanSpiderSpider(scrapy.Spider):
    #爬虫名字
    name = 'douban_spider'
    #容许的域名 爬取url都属于这个域名
    allowed_domains = ['movie.douban.com']
    #起始url
    start_urls = ['https://movie.douban.com/top250/']

    #默认解析方法
    def parse(self, response):
        # 注意在python语句中使用xpath如 注意与原来语句单双引号的问题
        movie_list=response.xpath("//ol[@class='grid_view']/li/div[@class='item']")
        for movie_item in movie_list:
            douban_item=DoubanItem()
            #xpath语句最后的text()是获取当前xpath的内容
            # scrapy get() getall()方法得到xpath路径的值 两种方法不一样请百度
            douban_item['serial_number'] = movie_item.xpath(".//em/text()").get()
            douban_item['movie_name'] = movie_item.xpath(".//span[@class='title']/text()").get()
            #介绍的内容很是不规范而且有好多行,首先使用getall()来获取,而后咱们要对其进行处理
            content = movie_item.xpath(".//div[@class='bd']/p[1]/text()").getall()
            #处理
            contient_introduce=''
            for conitem in content:
                content_s=''.join(conitem.split())
                contient_introduce=contient_introduce+content_s+'  '
            #赋值
            douban_item['introduce'] = contient_introduce
            douban_item['star'] = movie_item.xpath(".//span[@class='rating_num']/text()").get()
            douban_item['evaluate'] = movie_item.xpath(".//div[@class='star']/span[4]/text()").get()
            douban_item['describe'] = movie_item.xpath(".//div[@class='bd']/p[2]/span/text()").get()
            #咱们须要把获取到的东西yield到douban_item中,不然咱们的管道pipelines.py没法接收数据
            yield douban_item

        #咱们须要自动翻页到下一页去解析数据
        next_linkend=response.xpath("//span[@class='next']/a/@href").get()
        #判断next_linkend是否存在
        if next_linkend:
            next_link = 'https://movie.douban.com/top250/'+next_linkend
            #一样须要yield提交到调度器中 同时添加一个回调函数(刚刚编写的数据提取函数)
            yield scrapy.Request(next_link,callback=self.parse)

数据存储

咱们可使用命令直接将数据保存到 json或者csv文件以下

仍是使用命令行   cd到项目目录  

输入命令  scrapy crawl douban_spider -o test.json 就能够获得一个json文件

输入命令  scrapy crawl douban_spider -o test.csv  就能够获得一个csv文件

这个csv文件能够直接用excel打开浏览,可是咱们会发现存在乱码,咱们能够先用notepad++打开文件改下编码方式而后保存再用excel打开便可

存储到数据库

接下来咱们须要对pipelines.py进行编写,将数据存储到mongodb中

注意咱们须要在setting.py中将 ITEM_PIPELINES 的注释关掉,这样才能正常的运行pipelines.py

pipelines.py代码:

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

# 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

import pymongo
#链接本地数据库   远程也能够
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
#数据库名称
mydb = myclient["douban"]
#数据表名称
mysheet = mydb["movie"]

class DoubanPipeline(object):
    #此中的item就是刚刚yield回来的
    def process_item(self, item, spider):
        data=dict(item)
        #插入数据
        mysheet.insert(data)
        return item

如今运行 main.py 数据就存储到数据库之中了,咱们能够打开数据库查看数据

至此,咱们的爬虫项目能够说已经完成了。


 

爬虫假装

  • ip代理中间件
  • user-agent中间件

ip代理须要购买服务器而后可使用先不提了 

咱们尝试下user-agent中间件

编写middlewares.py再最后新加入咱们本身编写的类(文件最上端要 import random):

class my_useragent(object):
    def process_request(self,request,spider):
        USER_AGENT_LIST = [
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
            "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
            "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)",
            "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
            "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
            "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
            "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
        ]
        agent = random.choice(USER_AGENT_LIST)
        request.headers['User_Agent'] = agent

而后去 settings.py 中开启中间件并修改成咱们刚刚建立的类以下图

而后再运行 main.py 就都OK了。

相关文章
相关标签/搜索