例のクローラフレームのPython Scrapy

導入前に、関連する知識を持っているscrapyが、あなたの参照の研究のために、小さな例であることをここでは、関連する事例を紹介しませんでした。

注:以降のPythonのバージョンを強調していない場合、デフォルトはpython3.xです。

クロール対象

ここで絵を見つけるための簡単なウェブサイト、情報オフ最初の写真を撮ります。

サイトのURL:http://www.58pic.com/c/

プロジェクトを作成します。

ターミナルコマンドラインは、次のコマンドを実行します

scrapy startprojectのAdilCrawler

 

コマンドが実行された後、プロジェクトは以下の構造を生成します。

 

次のように実行結果があります

 

次のプロジェクトへの迅速、CD上に示したように、あなたは、ドメイン名example.com爬虫類という名前のファイルの例を作成するためにscrapy genspider example.comなどのコマンドを実行することができます。

 

書き込みitems.py

ここでは簡単に名前、画像やトピックに関するその他の情報の画像を捕獲しました。

复制代码
# -  *  - コーディング:UTF-8  -  *  - 

#あなたの掻き取りのアイテムはこちらモデルを定義します
#がでマニュアルを参照してください:
#https://doc.scrapy.org/en/latest/topics/items.html

輸入scrapy

クラスAdilcrawlerItem(scrapy.Item):
    #のようにここにあなたの項目のフィールドを定義します。
    #名前= scrapy.Field()

    著者= scrapy.Field()#著者

    テーマ= scrapy.Field()#テーマ
复制代码

 

クモのファイルを書き込みます 

ディレクトリにAdilCrawler、爬虫類の基礎を作成するためのコマンドを使用します。

 scrapy genspider thousandPic www.58pic.com

爬虫類名として#ThousandPic、www.58pic.com爬虫類のスコープ

 

执行命令后会在spiders文件夹中创建一个thousandPic.py的文件,现在开始对其编写:

 

复制代码
# -*- coding: utf-8 -*-
import scrapy
# 爬虫 小试

class ThousandpicSpider(scrapy.Spider):
    name = 'thousandPic'
    allowed_domains = ['www.58pic.com']
    start_urls = ['http://www.58pic.com/c/']

    def parse(self, response):

        '''
        查看页面元素
         /html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()
          因为页面中 有多张图,而图是以 /html/body/div[4]/div[3]/div[i]  其中i  为变量 作为区分的 ,所以为了获取当前页面所有的图
          这里 不写 i 程序会遍历 该 路径下的所有 图片。
        '''# author 作者
        # theme  主题
        author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
        theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
        # 使用 爬虫的log 方法在控制台输出爬取的内容。
        self.log(author)
        self.log(theme)
        # 使用遍历的方式 打印出 爬取的内容,因为当前一页有20张图片。
        for i in range(1, 21):
            print(i,' **** ',theme[i - 1], ': ',author[i - 1] )
复制代码

 

 执行命令,查看打印结果

scrapy crawl thousandPic

 

结果如下,其中DEBUG为 log 输出。

 

代码优化

引入 item AdilcrawlerItem

复制代码
# -*- coding: utf-8 -*-
import scrapy
# 这里使用 import 或是 下面from 的方式都行,关键要看 当前项目在pycharm的打开方式,是否是作为一个项目打开的,建议使用这一种方式。
import AdilCrawler.items as items

# 使用from 这种方式,AdilCrawler 需要作为一个项目打开。
# from AdilCrawler.items import AdilcrawlerItem


class ThousandpicSpider(scrapy.Spider):
    name = 'thousandPic'
    allowed_domains = ['www.58pic.com']
    start_urls = ['http://www.58pic.com/c/']

    def parse(self, response):

        '''
        查看页面元素
         /html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()
          因为页面中 有多张图,而图是以 /html/body/div[4]/div[3]/div[i]  其中i  为变量 作为区分的 ,所以为了获取当前页面所有的图
          这里 不写 i 程序会遍历 该 路径下的所有 图片。
        '''

        item = items.AdilcrawlerItem()

        # author 作者
        # theme  主题

        author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()

        theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()

        item['author'] = author
        item['theme']  = theme

        return item
复制代码
 
再次运营爬虫,执行结果如下

 

保存结果到文件

执行命令如下
scrapy crawl thousandPic -o items.json

会生成如图的文件

 

再次优化,使用 ItemLoader 功能类

使用itemLoader ,以取代杂乱的extract()和xpath()。

代码如下: 

复制代码
# -*- coding: utf-8 -*-
import scrapy
from AdilCrawler.items import AdilcrawlerItem

# 导入 ItemLoader 功能类
from scrapy.loader import ItemLoader

# optimize  优化
# 爬虫项目优化

class ThousandpicoptimizeSpider(scrapy.Spider):
    name = 'thousandPicOptimize'
    allowed_domains = ['www.58pic.com']
    start_urls = ['http://www.58pic.com/c/']

    def parse(self, response):

        '''
        查看页面元素
         /html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()
          因为页面中 有多张图,而图是以 /html/body/div[4]/div[3]/div[i]  其中i  为变量 作为区分的 ,所以为了获取当前页面所有的图
          这里 不写 i 程序会遍历 该 路径下的所有 图片。
        '''

        # 使用功能类 itemLoader,以取代 看起来杂乱的 extract() 和 xpath() ,优化如下
        i = ItemLoader(item = AdilcrawlerItem(),response = response )
        # author 作者
        # theme  主题
        i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
        i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')
        return i.load_item()
复制代码

  

编写pipelines文件 

 默认pipelines.py 文件

复制代码
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


class Adilcrawler1Pipeline(object):
    def process_item(self, item, spider):
        return item
复制代码

 

优化后代码如下

 

复制代码
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json

class AdilcrawlerPipeline(object):
    '''
        保存item数据
    '''

    def __init__(self):
        self.filename = open('thousandPic.json','w')

    def process_item(self, item, spider):

        #  ensure_ascii=False 可以解决 json 文件中 乱码的问题。
        text = json.dumps(dict(item), ensure_ascii=False) + ',\n'   #  这里是一个字典一个字典存储的,后面加个 ',\n' 以便分隔和换行。
        self.filename.write(text)

        return item

    def close_spider(self,spider):
        self.filename.close()
复制代码

 

settings文件设置

修改settings.py配置文件

找到pipelines 配置进行修改

复制代码
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
# ITEM_PIPELINES = {
#    'AdilCrawler.pipelines.AdilcrawlerPipeline': 300,
# }

# 启动pipeline 必须将其加入到“ITEM_PIPLINES”的配置中
# 其中根目录是tutorial,pipelines是我的pipeline文件名,TutorialPipeline是类名
ITEM_PIPELINES = {
    'AdilCrawler.pipelines.AdilcrawlerPipeline': 300,
}

# 加入后,相当于开启pipeline,此时在执行爬虫,会执行对应的pipelines下的类,并执行该类相关的方法,比如这里上面的保存数据功能。
复制代码

 

执行命令

scrapy crawl thousandPicOptimize

执行后生成如下图文件及保存的数据

 

 

使用CrawlSpider类进行翻页抓取

使用crawl 模板创建一个 CrawlSpider 
执行命令如下
scrapy genspider -t crawl thousandPicPaging www.58pic.com

items.py 文件不变,查看 爬虫 thousandPicPaging.py 文件

复制代码
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class ThousandpicpagingSpider(CrawlSpider):
    name = 'thousandPicPaging'
    allowed_domains = ['www.58pic.com']
    start_urls = ['http://www.58pic.com/']

    rules = (
        Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        i = {}
        #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
        #i['name'] = response.xpath('//div[@id="name"]').extract()
        #i['description'] = response.xpath('//div[@id="description"]').extract()
        return i
复制代码

 

修改后如下

复制代码
# -*- coding: utf-8 -*-
import scrapy
# 导入链接规则匹配类,用来提取符合规则的连接
from scrapy.linkextractors import LinkExtractor
# 导入CrawlSpider类和Rule
from scrapy.spiders import CrawlSpider, Rule
import AdilCrawler.items as items

class ThousandpicpagingSpider(CrawlSpider):
    name = 'thousandPicPaging'
    allowed_domains = ['www.58pic.com']
    # 修改起始页地址
    start_urls = ['http://www.58pic.com/c/']

    # Response里链接的提取规则,返回的符合匹配规则的链接匹配对象的列表
    # http://www.58pic.com/c/1-0-0-03.html  根据翻页连接地址,找到 相应的 正则表达式   1-0-0-03  -> \S-\S-\S-\S\S  而且 这里使用 allow
    # 不能使用 restrict_xpaths ,使用 他的话,正则将失效
    page_link = LinkExtractor(allow='http://www.58pic.com/c/\S-\S-\S-\S\S.html', allow_domains='www.58pic.com')

    rules = (
        # 获取这个列表里的链接,依次发送请求,并且继续跟进,调用指定回调函数处理
        Rule(page_link, callback='parse_item', follow=True),  # 注意这里的 ',' 要不会报错
    )


    # 加上这个 方法是为了 解决 parse_item() 不能抓取第一页数据的问题 parse_start_url 是 CrawlSpider() 类下的方法,这里重写一下即可
    def parse_start_url(self, response):
        i = items.AdilcrawlerItem()
        author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
        theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
        i['author'] = author
        i['theme'] = theme

        yield i

    # 指定的回调函数
    def parse_item(self, response):
        i = items.AdilcrawlerItem()
        author = response.xpath('/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()').extract()
        theme = response.xpath('/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()').extract()
        i['author'] = author
        i['theme'] = theme
        yield i
复制代码

 

再次执行 

scrapy crawl thousandPicPaging

 

查看执行结果,可以看到是有4页的内容

 

再次优化引入 ItemLoader  类

复制代码
# -*- coding: utf-8 -*-
import scrapy
# 导入链接规则匹配类,用来提取符合规则的连接
from scrapy.linkextractors import LinkExtractor
# 导入CrawlSpider类和Rule
from scrapy.loader import ItemLoader
from scrapy.spiders import CrawlSpider, Rule
import AdilCrawler.items as items

class ThousandpicpagingopSpider(CrawlSpider):
    name = 'thousandPicPagingOp'
    allowed_domains = ['www.58pic.com']
    # 修改起始页地址
    start_urls = ['http://www.58pic.com/c/']

    # Response里链接的提取规则,返回的符合匹配规则的链接匹配对象的列表
    # http://www.58pic.com/c/1-0-0-03.html  根据翻页连接地址,找到 相应的 正则表达式   1-0-0-03  -> \S-\S-\S-\S\S  而且 这里使用 allow
    # 不能使用 restrict_xpaths ,使用 他的话,正则将失效
    page_link = LinkExtractor(allow='http://www.58pic.com/c/\S-\S-\S-\S\S.html', allow_domains='www.58pic.com')

    rules = (
        # 获取这个列表里的链接,依次发送请求,并且继续跟进,调用指定回调函数处理
        Rule(page_link, callback='parse_item', follow=True),  # 注意这里的 ',' 要不会报错
    )

    # 加上这个 方法是为了 解决 parse_item() 不能抓取第一页数据的问题 parse_start_url 是 CrawlSpider() 类下的方法,这里重写一下即可
    def parse_start_url(self, response):

        i = ItemLoader(item = items.AdilcrawlerItem(),response = response )
        i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
        i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')

        yield  i.load_item()

    # 指定的回调函数
    def parse_item(self, response):
        i = ItemLoader(item = items.AdilcrawlerItem(),response = response )
        i.add_xpath('author','/html/body/div[4]/div[3]/div/a/p[2]/span/span[2]/text()')
        i.add_xpath('theme','/html/body/div[4]/div[3]/div/a/p[1]/span[1]/text()')

        yield  i.load_item()
复制代码

 

执行结果是一样的。

最后插播一条 在线正则表达式测试 工具的广告,地址: http://tool.oschina.net/regex/

应用如下

おすすめ

転載: www.cnblogs.com/longshao1239/p/12054164.html