发表文章

[最新] scrapy 爬虫的一些经验

seahome81 1月前 8

新手初学scrapy写爬虫,其中碰到的问题记录下,以备不时之需。

1、在一个爬虫里调用另外一个爬虫

需要导入的模块:
from scrapy.cmdline import execute
import test1.spiders.content_spider
import scrapy
调用的方式:
execute(['scrapy', 'crawl', 'contentspider', "-a", "param1="+value1, "-a" "param2="+value2, 
         "-a" "param3="+value3, "-a" "param4="+value4, "-a" "param5="+value5, 
         "-a" "param6="+value6])

传几个参数,就需几个"-a",上述例子的参数可以使用list包装,这样写起来更简洁。

2、使用redis模块,实现爬虫的增量去重(此处考虑爬取链接的增量去重)

需要导入的模块:

import redis

# 定义去重暂存数据库
redis_db = redis.Redis(host='127.0.0.1', port=6379, db=1)  # 连接本地redis,db数据库默认连接到0号库,写的是索引值
redis_data_dict = ''  # key的名字,里面的内容随便写,这里的key相当于字典名称,而不是key值。为了后面引用而建的
# 在pipeline的初始化函数里从mssql数据库取数写入到暂存数据库redis_db里,用于去重比对
class Test1Pipeline(object):
    def __init__(self):
        redis_db.flushdb()  # 清空当前数据库中的所有 key,为了后面将mysql数据库中的数据全部保存进去
        if redis_db.hlen(redis_data_dict) == 0:  # 判断redis数据库中的key,若不存在就读取mysql数据并临时保存在redis中
            df = ms.ExecQuery('select lj from testtable')  # 读取mssql中的数据
            # print(df)
            for url in df:
                redis_db.hset(redis_data_dict, url[0], 0)  # 把每个url写入field中,value值随便设,我设置的0  key field value 三者的关系

在process_item里对当前爬取的数据进行去重

def process_item(self, item, spider):
    """
    比较爬取的数据在数据库中是否存在,不存在则插入数据库
    :param item: 爬取到的数据
    :param spider: /
    """
    if redis_db.hexists(redis_data_dict, item['lj']):  # 比较的是redis_data_dict里面的field
        print("数据库已经存在该条数据,不再继续追加")
    else:
        数据入库操作
    return item

3、一个爬虫多次对item进行操作时,需注意itme内容变化的问题

def subparse(self, response):
    item操作
    yield item
    yield scrapy.Request(url=item['lj'], meta={'param1': param1, 'param2': param2, 'param3': param3},
                                 callback=self.contentparse, dont_filter=True)
    next_page = response.css('#pgt .nxt::attr(href)').extract()  # 获取下一页链接
    if next_page:
        yield scrapy.Request(url=next_page[0], callback=self.subparse)

以上例子,回调函数contentparse不能直接在函数读取item,只能通过参数传递来获得函数所需的数据,因为在subparse会调用自己,并对item进行修改,contentparse无法通过读取item获取正确的数据(即回调contentparse还没运行,item数据就被subparse修改了)。
 

相关推荐
最新评论 (0)
返回
发表文章
seahome81
文章数
3
评论数
5
注册排名
185501