• Scrapy 爬虫完整案例-进阶篇


     Scrapy 爬虫完整案例-进阶篇

    1.1  进阶篇案例一

    案例:爬取豆瓣电影 top250( movie.douban.com/top250 )的电影数据,并保存在 MongoDB 中。

     

    案例步骤:

    第一步:明确爬虫需要爬取的内容。

    我们做爬虫的时候,需要明确需要爬取的内容,豆瓣电影 TOP 250,我们需要抓取每一部电影的名字,电影的描述信息(包括导演、主演、电影类型等等),电影的评分,以及电影中最经典或者脍炙人口的一句话。

    例如:肖申克的救赎

     

    电影的名字:肖申克的救赎。

    电影信息(导演:弗兰克·德拉邦特;主演:蒂姆·罗宾斯 / 摩根·弗里曼 / 鲍勃·冈顿 / 威廉姆·赛德勒 / 克兰西·布朗 / 更多...;电影类型:剧情 / 犯罪。)

    豆瓣电影评分:9.6。

    脍炙人口的一句话:希望让人自由。

    第二步:创建爬虫项目。

    在 dos下切换到目录

    D:scrapy_project

     

    新建一个新的爬虫项目:scrapy startproject douban

     

    第三步:创建爬虫。

    在 dos下切换到目录。

    D:scrapy_projectdoubandoubanspiders

    用命令 scrapy genspider doubanmovie "movie.douban.com" 创建爬虫。

     

    第四步: 开始前的准备工作。

    (一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:

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

    from scrapy import cmdline

    cmdline.execute("scrapy crawl doubanmovie".split())

     

    (二)、修改 settings 中的 ROBOTSTXT_OBEY = True 参数为 False,因为默认为 True,就是要遵守 robots.txt 的规则, robots.txt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在 Scrapy 启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。查看 robots.txt 可以直接网址后接 robots.txt 即可。

    例如百度:https://www.baidu.com/robots.txt

    修改 settings 文件。

     

    (三)、settings.py 里添加 USER_AGENT。

     

    (四)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。

    COOKIES_ENABLED = False

     

    第五步: 定义 Item,编写 items.py 文件。

    import scrapy

    class DoubanItem(scrapy.Item):

        # 电影标题

        title = scrapy.Field()

        # 电影信息

        bd = scrapy.Field()

        # 豆瓣评分

        star = scrapy.Field()

        # 脍炙人口的一句话

    quote = scrapy.Field()

    第六步: 查看HTML源码,使用XPath helper爬虫插件一起查看需要爬取的字段的 xpath 路径。

    # 电影标题

    item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]

     

    # 电影信息

    item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]

     

    # 豆瓣评分

    item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]

     

    # 脍炙人口的一句话

    quote = each.xpath(".//p[@class='quote']/span/text()").extract()

     

    备注:extract()返回的是一个列表,列表里的每个元素是一个对象,extract()把这些对象转换成 Unicode 字符串。

    第七步: 分析网站分页的 URL 规律。

     

    第一页的链接地址:

    https://movie.douban.com/top250?start=0

    第二页的链接地址:

    https://movie.douban.com/top250?start=25

    最十页的链接地址:

    https://movie.douban.com/top250?start=225

    通过分析我们得知,每一页的的链接地址 start 的值递增 25,就是下一页的地址。

    第八步: 编写爬虫文件。

    import scrapy,sys,os

    path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    sys.path.append(path)

    from douban.items import DoubanItem

     

    class DoubamovieSpider(scrapy.Spider):

        name = "doubanmovie"

        allowed_domains = ["movie.douban.com"]

        offset = 0

        url = "https://movie.douban.com/top250?start="

        start_urls = (

                url + str(offset),

        )

     

        def parse(self, response):

            item = DoubanItem()

            movies = response.xpath("//div[@class='info']")

     

            for each in movies:

                # 电影标题

                item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]

                # 电影信息

                item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]

                # 豆瓣评分

                item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]

                # 脍炙人口的一句话

                quote = each.xpath(".//p[@class='quote']/span/text()").extract()

                if len(quote) != 0:

                    item['quote'] = quote[0]

                yield item

     

            if self.offset < 225:

                self.offset += 25

                yield scrapy.Request(self.url + str(self.offset), callback = self.parse)

    第九步:在settings.py文件里设置管道文件。

    ITEM_PIPELINES = {

       'douban.pipelines.DoubanPipeline': 300,

    }

     

    第十步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。

    MongoDB中创建一个叫"Douban"的库。

    MongoDB 创建数据库的语法格式如下:

    use DATABASE_NAME

    如果数据库不存在,则创建数据库,否则切换到指定数据库。

     

    备注:刚创建的数据库 Douban并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。

    创建表:db.createCollection("doubanmovies")

    语法格式:

    db.createCollection(name, options)

     

    创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。

     

    查看表:show collections

     

    第十一步:在settings.py文件里配置 MongoDB 连接配置项

    # MONGODB 主机名

    MONGODB_HOST = "127.0.0.1"

    # MONGODB 端口号

    MONGODB_PORT = 27017

    # 数据库名称

    MONGODB_DBNAME = "Douban"

    # 存放数据的表名称

    MONGODB_SHEETNAME = "doubanmovies"

     

    第十二步: 编写 pipelines 管道文件(把数据存储到 MongoDB)。

    import pymongo

    from scrapy.conf import settings

     

    class DoubanPipeline(object):

        def __init__(self):

            host = settings["MONGODB_HOST"]

            port = settings["MONGODB_PORT"]

            dbname = settings["MONGODB_DBNAME"]

            sheetname= settings["MONGODB_SHEETNAME"]

     

            # 创建MONGODB数据库链接

            client = pymongo.MongoClient(host = host, port = port)

            # 指定数据库

            mydb = client[dbname]

            # 存放数据的数据库表名

            self.sheet = mydb[sheetname]

     

        def process_item(self, item, spider):

            data = dict(item)

            self.sheet.insert(data)

            return item

    第十三步: 执行run.py文件,运行爬虫。

     

    第十四步: 查看 MongoDB 数据库

     

    显示的只是一部分数据(Type "it" for more),如果想看完整的数据,可以通过 MongoDB 数据库自带的图形化客户端工具(MongoDB Compass Community)查看。

     

    1.2  进阶篇案例二

    案例:使用下载中间件(Downloader Middlewares)改写爬取豆瓣电影top250案例

    案例步骤:

    第一步:创建爬虫项目。

    在 dos下切换到目录

    D:scrapy_project

     

    新建一个新的爬虫项目:scrapy startproject douban2

     

    第二步:创建爬虫。

    在 dos下切换到目录。

    D:scrapy_projectdouban2douban2spiders

    用命令 scrapy genspider doubanmovie2 "movie.douban.com" 创建爬虫。

     

    第三步: 开始前的准备工作。

    (一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:

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

    from scrapy import cmdline

    cmdline.execute("scrapy crawl doubanmovie".split())

     

    (二)、修改 settings 中的 ROBOTSTXT_OBEY = True 参数为 False,因为默认为 True,就是要遵守 robots.txt 的规则, robots.txt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在 Scrapy 启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。查看 robots.txt 可以直接网址后接 robots.txt 即可。

    例如百度:https://www.baidu.com/robots.txt

    修改 settings 文件。

     

    (三)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。

    COOKIES_ENABLED = False

     

    备注:截图使用的是案例一,步骤参考案例一。

    第四步: 定义 Item,编写 items.py 文件。

    import scrapy

    class DoubanItem(scrapy.Item):

        # 电影标题

        title = scrapy.Field()

        # 电影信息

        bd = scrapy.Field()

        # 豆瓣评分

        star = scrapy.Field()

        # 脍炙人口的一句话

    quote = scrapy.Field()

    第五步: 编写爬虫文件。

    import scrapy,sys,os

    path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    sys.path.append(path)

    from douban.items import DoubanItem

     

    class DoubamovieSpider(scrapy.Spider):

        name = "doubanmovie"

        allowed_domains = ["movie.douban.com"]

        offset = 0

        url = "https://movie.douban.com/top250?start="

        start_urls = (

                url + str(offset),

        )

     

        def parse(self, response):

            item = DoubanItem()

            movies = response.xpath("//div[@class='info']")

     

            for each in movies:

                # 电影标题

                item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]

                # 电影信息

                item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]

                # 豆瓣评分

                item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]

                # 脍炙人口的一句话

                quote = each.xpath(".//p[@class='quote']/span/text()").extract()

                if len(quote) != 0:

                    item['quote'] = quote[0]

                yield item

     

            if self.offset < 225:

                self.offset += 25

                yield scrapy.Request(self.url + str(self.offset), callback = self.parse)

    第六步:在settings.py文件里设置管道文件。

    ITEM_PIPELINES = {

       'douban.pipelines.DoubanPipeline': 300,

    }

    第七步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。

    MongoDB中创建一个叫"Douban"的库。

     

    MongoDB 创建数据库的语法格式如下:

    use DATABASE_NAME

    如果数据库不存在,则创建数据库,否则切换到指定数据库。

     

    备注:刚创建的数据库 Douban 并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。

    创建表:db.createCollection("doubanmovies")

    语法格式:

    db.createCollection(name, options)

     

    创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。

     

    查看表:show collections

     

    第八步:在settings.py文件里配置 MongoDB 连接配置项

    # MONGODB 主机名

    MONGODB_HOST = "127.0.0.1"

    # MONGODB 端口号

    MONGODB_PORT = 27017

    # 数据库名称

    MONGODB_DBNAME = "Douban"

    # 存放数据的表名称

    MONGODB_SHEETNAME = "doubanmovies"

     

    第九步: 编写 pipelines 管道文件(把数据存储到 MongoDB)。

    import pymongo

    from scrapy.conf import settings

     

    class DoubanPipeline(object):

        def __init__(self):

            host = settings["MONGODB_HOST"]

            port = settings["MONGODB_PORT"]

            dbname = settings["MONGODB_DBNAME"]

            sheetname= settings["MONGODB_SHEETNAME"]

     

            # 创建MONGODB数据库链接

            client = pymongo.MongoClient(host = host, port = port)

            # 指定数据库

            mydb = client[dbname]

            # 存放数据的数据库表名

            self.sheet = mydb[sheetname]

     

        def process_item(self, item, spider):

            data = dict(item)

            self.sheet.insert(data)

            return item

    第十步: 在settings.py文件里添加下载中间件(Downloader Middlewares)字段。

    DOWNLOADER_MIDDLEWARES = {

        'douban.middlewares.RandomUserAgent': 100,

        'douban.middlewares.RandomProxy': 200,

    }

    USER_AGENTS = [

        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)',

        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)',

        'Opera/9.27 (Windows NT 5.2; U; zh-cn)',

        'Opera/8.0 (Macintosh; PPC Mac OS X; U; en)',

        'Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0',

        'Mozilla/5.0 (Linux; U; Android 4.0.3; zh-cn; M032 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',

        'Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13'

    ]

    PROXIES = [

            {"ip_port" :"121.42.140.113:16816", "user_passwd" : " xiao@123"},

            #{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

            #{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

            #{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

    ]

    【RandomUserAgent】:表示随机的 Agent 。

    【RandomProxy】:表示随机的代理 。

    代理可以去找免费的代理。

     

    也可以去购买私密代理。

    快代理:https://www.kuaidaili.com

     

    备注:代理分免费代理和私密代理,免费代理的账户和密码为空,私密代理有账户和密码,这需要在下载中间键 middlewares.py 程序里增加判断"user_passwd"有没有值,如果没有值就不用。

    第十一步: 编写下载中间键 middlewares.py 文件。

    import random,os,sys

    import base64

    path = os.path.dirname(os.path.abspath(__file__))

    sys.path.append(path)

    from douban2.settings import USER_AGENTS

    from douban2.settings import PROXIES

     

    # 随机的User-Agent

    class RandomUserAgent(object):

        def process_request(self, request, spider):

            useragent = random.choice(USER_AGENTS)

            #设置请求头的默认值

            request.headers.setdefault("User-Agent", useragent)

     

    class RandomProxy(object):

        def process_request(self, request, spider):

            proxy = random.choice(PROXIES)

    # request.meta['proxy']表示当前请求使用的代理

            if proxy['user_passwd'] is None:

                # 没有代理账户验证的代理使用方式

                request.meta['proxy'] = "http://" + proxy['ip_port']

            else:

                # 对账户密码进行base64编码转换

                base64_userpasswd = base64.b64encode(proxy['user_passwd'])

                # 对应到代理服务器的信令格式里

                request.headers['Proxy-Authorization'] = 'Basic ' + base64_userpasswd

                request.meta['proxy'] = "http://" + proxy['ip_port']

    第十二步: 在 settings.py 文件里设置延迟下载(防止访问过于频繁,设置为 2 秒 或更高)

    DOWNLOAD_DELAY = 3

     

    第十三步: 执行run.py文件,运行爬虫。

     

    第十四步: 查看 MongoDB 数据库

     

    显示的只是一部分数据(Type "it" for more),如果想看完整的数据,可以通过 MongoDB 数据库自带的图形化客户端工具(MongoDB Compass Community)查看。

     

     -------------------------------

    个人今日头条账号: 听海8   (上面上传了很多相关学习的视频以及我书里的文章,大家想看视频,可以关注我的今日头条)

     

     

     

  • 相关阅读:
    java泛型
    跨域传递
    laravel的一些语法
    去重
    laravel的一些查询语句
    mysql把之前表单进行拆分
    Laravel5.1接收json数据
    thinkphp5 composer安装验证码
    关于地图经纬度的问题
    tp5分组查询
  • 原文地址:https://www.cnblogs.com/tinghai8/p/9700300.html
Copyright © 2020-2023  润新知