Skip to content

Latest commit

 

History

History
204 lines (172 loc) · 9.72 KB

item.md

File metadata and controls

204 lines (172 loc) · 9.72 KB

talospider - item

2.1.item

目标值提取类,当时是看demiurge这个项目研究了下metaclass,可以说item部分是参考这个的。

item的目的是是提取目标值,默认需要提供html或者对应的url才会返回自定义的field(写scrapy应该很清楚要先在item定义field吧),利用lxml解析。

就算没有爬虫模块,这个部分是可以单独使用的,目的时针对当爬取到目标页面那层的时候,进行目标数据的提取,当前目标数据的提取情况分两种:

2.1.1.单页面单目标

比如这个网址http://book.qidian.com/info/1004608738

提取的对象很明确,这么多字段是一次结果,即一个页面一个目标,称之为单一目标获取,字段如下:

field css_select
title .book-info>h1>em
author a.writer
cover a#bookImg>img
abstract div.book-intro>p
tag span.blue
latest_chapter div.detail>p.cf>a
latest_chapter_time div.detail>p.cf>em

使用起来很简单:

# -*- coding:utf-8 -*-
# !/usr/bin/env python
import time
from talospider import Item, TextField, AttrField
from pprint import pprint


class QidianItem(Item):
    title = TextField(css_select='.book-info>h1>em')
    author = TextField(css_select='a.writer')
    # 当提取的值是属性的时候,要定义AttrField
    cover = AttrField(css_select='a#bookImg>img', attr='src')
    abstract = TextField(css_select='div.book-intro>p')
    tag = TextField(css_select='span.blue')
    latest_chapter = TextField(css_select='li.update>div.detail>p.cf>a')
    latest_chapter_time = TextField(css_select='div.detail>p.cf>em')

    # 这里可以二次对获取的目标值进行处理,比如替换、清洗等
    def tal_title(self, title):
        # Clean your target value
        return title

    def tal_cover(self, cover):
        return 'http:' + cover

    # 当目标值的对象只有一个,默认将值提取出来,否则返回list,可以在这里定义一个函数进行循环提取
    def tal_tag(self, ele_tag):
        return '#'.join([i.text for i in ele_tag])

    def tal_latest_chapter_time(self, latest_chapter_time):
        return latest_chapter_time.replace(u'今天', str(time.strftime("%Y-%m-%d ", time.localtime()))).replace(u'昨日', str(
            time.strftime("%Y-%m-%d ", time.localtime(time.time() - 24 * 60 * 60))))


if __name__ == '__main__':
    # 获取值
    item_data = QidianItem.get_item(url='http://book.qidian.com/info/1004608738')
    pprint(item_data)
    # for python 2.7
    # import json
    # item_data = json.dumps(item_data, ensure_ascii=False)
    # print(item_data)

# output
{'abstract': '在破败中崛起,在寂灭中复苏。沧海成尘,雷电枯竭,那一缕幽雾又一次临近大地,世间的枷锁被打开了,一个全新的世界就此揭开神秘的一角……',
 'author': '辰东',
 'cover': 'http://qidian.qpic.cn/qdbimg/349573/1004608738/180',
 'latest_chapter': '第七百七十一章 神性粒子',
 'latest_chapter_time': '2017-11-22 22:57更新',
 'tag': '连载#签约#VIP',
 'title': '圣墟'}

写个类继承自Item就搞定了,ok

2.1.2.单页面多目标

比如https://movie.douban.com/top250

这个页面每页展示25部电影,我的爬虫目标就是每页的25部电影信息,所以这个目标页的目标数据是多个item的,对于这种情况,目标是需要循环获取的。

我在item中限制了一点,当你定义的爬虫类需要在某一页面循环获取你的目标时,则需要定义target_item属性。

对于豆瓣250这个页面,我们的目标是25部电影信息,所以该这样定义:

field css_select
target_item(必须) div.item
title span.title
cover div.pic>a>img
abstract span.inq
# 定义继承自item的爬虫类
class DoubanSpider(Item):
    target_item = TextField(css_select='div.item')
    title = TextField(css_select='span.title')
    cover = AttrField(css_select='div.pic>a>img', attr='src')
    abstract = TextField(css_select='span.inq')

    def tal_title(self, title):
        if isinstance(title, str):
            return title
        else:
            return ''.join([i.text.strip().replace('\xa0', '') for i in title])

items_data = DoubanSpider.get_items(url='https://movie.douban.com/top250')
result = []
for item in items_data:
    result.append({
        'title': item.title,
        'cover': item.cover,
        'abstract': item.abstract,
    }
pprint(result)
# 搞定输出
# [{'abstract': '希望让人自由。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.jpg',
#   'title': '肖申克的救赎/The Shawshank Redemption'},
#  {'abstract': '怪蜀黍和小萝莉不得不说的故事。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p511118051.jpg',
#   'title': '这个杀手不太冷/Léon'},
#  {'abstract': '风华绝代。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910813120.jpg',
#   'title': '霸王别姬'},
#  {'abstract': '一部美国近现代史。',
#   'cover': 'https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p510876377.jpg',
#   'title': '阿甘正传/Forrest Gump'},
#  {'abstract': '最美的谎言。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p510861873.jpg',
#   'title': '美丽人生/La vita è bella'},
#  {'abstract': '最好的宫崎骏,最好的久石让。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910830216.jpg',
#   'title': '千与千寻/千と千尋の神隠し'},
#  {'abstract': '拯救一个人,就是拯救整个世界。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p492406163.jpg',
#   'title': "辛德勒的名单/Schindler's List"},
#  {'abstract': '失去的才是永恒的。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p457760035.jpg',
#   'title': '泰坦尼克号/Titanic'},
#  {'abstract': '诺兰给了我们一场无法盗取的梦。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p513344864.jpg',
#   'title': '盗梦空间/Inception'},
#  {'abstract': '小瓦力,大人生。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p449665982.jpg',
#   'title': '机器人总动员/WALL·E'},
#  {'abstract': '每个人都要走一条自己坚定了的路,就算是粉身碎骨。',
#   'cover': 'https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p511146957.jpg',
#   'title': "海上钢琴师/La leggenda del pianista sull'oceano"},
#  {'abstract': '英俊版憨豆,高情商版谢耳朵。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p579729551.jpg',
#   'title': '三傻大闹宝莱坞/3 Idiots'},
#  {'abstract': '永远都不能忘记你所爱的人。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p524964016.jpg',
#   'title': "忠犬八公的故事/Hachi: A Dog's Tale"},
#  {'abstract': '天籁一般的童声,是最接近上帝的存在。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910824951.jpg',
#   'title': '放牛班的春天/Les choristes'},
#  {'abstract': '一生所爱。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p2455050536.jpg',
#   'title': '大话西游之大圣娶亲/西遊記大結局之仙履奇緣'},
#  {'abstract': '千万不要记恨你的对手,这样会让你失去理智。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1853232210.jpg',
#   'title': '教父/The Godfather'},
#  {'abstract': '人人心中都有个龙猫,童年就永远不会消失。',
#   'cover': 'https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p1910829638.jpg',
#   'title': '龙猫/となりのトトロ'},
#  {'abstract': '如果再也不能见到你,祝你早安,午安,晚安。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p479682972.jpg',
#   'title': '楚门的世界/The Truman Show'},
#  {'abstract': 'Tomorrow is another day.',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1963126880.jpg',
#   'title': '乱世佳人/Gone with the Wind'},
#  {'abstract': '那些吻戏,那些青春,都在影院的黑暗里被泪水冲刷得无比清晰。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1910901025.jpg',
#   'title': '天堂电影院/Nuovo Cinema Paradiso'},
#  {'abstract': '平民励志片。',
#   'cover': 'https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p1312700628.jpg',
#   'title': '当幸福来敲门/The Pursuit of Happyness'},
#  {'abstract': '满满温情的高雅喜剧。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p1454261925.jpg',
#   'title': '触不可及/Intouchables'},
#  {'abstract': '邪恶与平庸蛰伏于同一个母体,在特定的时间互相对峙。',
#   'cover': 'https://img1.doubanio.com/view/movie_poster_cover/ipst/public/p1910926158.jpg',
#   'title': '搏击俱乐部/Fight Club'},
#  {'abstract': '1957年的理想主义。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p2173577632.jpg',
#   'title': '十二怒汉/12 Angry Men'},
#  {'abstract': '香港电影史上永不过时的杰作。',
#   'cover': 'https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p2233971046.jpg',
#   'title': '无间道/無間道'}]