scrapy中遇到的问题与解决

Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。
因为好像这个用的比较多,所以看看用这个框架该怎么写爬虫。其实不难,但是中间出了很多神奇的小问题。


输出不正确、改代码结果不变?

其实是因为反复使用命令

scrapy crawl spider -o 1.json

时候,增加的输出数据不会覆盖,而是继续往后面添加。


request不执行

找了半天不知道为啥,其中一个比较靠谱的是

Request(url,meta={'item':item},callback=self.parse2, dont_filter=True)

dont_filter=Trueallowed_domains失效了。但是改过了还是不行。
最终结果发现改的文件和运行的文件不一样……
为什么会这样呢?我中间做了一部分实现了初始功能,就重命名了备份,然而执行命令行竟然一直在执行备份文件。。


输出为utf-8格式(保存中文)

更改pipeline文件。

import json
import codecs
class WebPipeline(object):
    # def process_item(self, item, spider):
    #     return item
    def __init__(self):
        # self.file = open('data.json', 'wb')
        self.file = codecs.open(
            'scraped_data_utf8.json', 'w', encoding='utf-8')
    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"
        self.file.write(line)
        return item
    def spider_closed(self, spider):
        self.file.close()
ITEM_PIPELINES = {
   'web.pipelines.WebPipeline': 300,
}

scrapy抓取到中文,保存到json文件为unicode,如何解决


如何在解析函数之间传递值?

一种常见的情况:在parse中给item某些字段提取了值,但是另外一些值需要在parse_item中提取,这时候需要将parse中的item传到parse_item方法中处理,显然无法直接给parse_item设置而外参数。 Request对象接受一个meta参数,一个字典对象,同时Response对象有一个meta属性可以取到相应request传过来的meta。所以解决上述问题可以这样做:

def parse(self, response):
    # item = ItemClass()
    yield Request(url, meta={'item': item},callback=self.parse_item)

def parse_item(self, response):
    item = response.meta['item']
    item['field'] = value
    yield item

Some Experiences Of Using Scrapy


使用ImagesPipeline下载

# setting.py
ITEM_PIPELINES = ['demo.pipelines.MyImagesPipeline']  # ImagePipeline的自定义实现类
IMAGES_STORE = 'D:\\dev\\python\\scrapy\\demo\\img'   # 图片存储路径
IMAGES_EXPIRES = 90                                   # 过期天数
IMAGES_MIN_HEIGHT = 100                               # 图片的最小高度
IMAGES_MIN_WIDTH = 100                                # 图片的最小宽度
# 图片的尺寸小于IMAGES_MIN_WIDTH*IMAGES_MIN_HEIGHT的图片都会被过滤

ImagePipeline
需要在自定义的ImagePipeline类中重载的方法:get_media_requests(item, info)和item_completed(results, items, info)。
正如工作流程所示,Pipeline将从item中获取图片的URLs并下载它们,所以必须重载get_media_requests,并返回一个Request对象,这些请求对象将被Pipeline处理,当完成下载后,结果将发送到item_completed方法,这些结果为一个二元组的list,每个元祖的包含(success, image_info_or_failure)。 * success: boolean值,true表示成功下载 * image_info_or_error:如果success=true,image_info_or_error词典包含以下键值对。失败则包含一些出错信息。 * url:原始URL * path:本地存储路径 * checksum:校验码。

from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy.http import Request

class MyImagesPipeline(ImagesPipeline):

    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            yield Request(image_url)


    def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

scrapy 下载图片 ImagesPipeline
扩展Media Pipeline

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值