scrapy断点爬取需要注意的问题

一、命令行直接敲一行代码,优点:该方法很简单,懒人专用2.该方法不稳定,有时候没效果,具体原因暂时不清楚,具体介绍如下:
1.执行命令scrapy crawl bdbk -s JOBDIR=job_info/001
2.重新爬取时,一定要注意文件里是否有数据,如果有的话,千万不要以w或wb形式写入,否则原先内容会被覆盖。要以a或ab形式写入。
二、将已经爬取的url整理出来,每个url经过md5加密压缩,后置于集合中,每次爬取时,判断该集合中是否有该元素,有的话,pass掉,没的话继续爬。爬取大量数据时,经过md5加密压缩成较小的存储空间的文件,方便大规模抓取。优点:方法很稳定,效果很好,缺点:抓取数量过多时,可能会影响抓取效率,每一个待抓的url都要和集合中的元素对比,空间时间复杂度高。

from scrapy import Request,Spider
from crawler.items import BdbkItem
import logging
import hashlib
#  将已经抓取的url置于集合中
def creat_set():
    with open('/home/tml-1/PycharmProjects/untitled/stored') as f:
        data=f.read().lstrip('{').rstrip('}').split(', ')
        url_st=set()
        for i in data:
            url_st.add(i.rstrip('\'').lstrip('\'').rstrip('\\n'))
    return  url_st

#  给每个已经抓取的url加密成16位的md5值
def creat_md5(url):
    m=hashlib.md5()
    m.update(url.encode('utf-8'))
    return m.hexdigest()[8:-8]


class BaidubaikeSpider(Spider):
    name = "BaiduBaike"
    allowed_domains = ["baike.baidu.com"]
    start_urls = 'https://baike.baidu.com/item/%E5%88%98%E7%82%B3%E6%A3%AE/2294673'
    base_url = 'https://baike.baidu.com'  # 百科中每个条目都具有的url
    shared_str = '/item/'  # 属于百科的链接中都具有的str
    set_stored=creat_set()

    def start_requests(self):
        yield Request(url=self.start_urls, callback=self.parse)

    def parse(self, response):

        item = BdbkItem()  # 实例化BDBKItem类
        if response.status == 200:  # 请求成功,执行以下代码
            url_list = response.xpath("//a/@href")  # 获取页面中所有链接
            item['url'] = response.url  # 获取当前百科条目的url,置于item中
            item['title'] = response.xpath("//h1/text()").extract_first()  # 获取当前百科条目的名称,置于item中
            #item['time'] = time.ctime()

            #self.count+=1
            #logging.debug("这是debug日志,item数量{}".format(str(self.count)))
            contents = response.xpath("//div[@class='para']")  # 获取具有所有文本的所有div元素
            text1 = []  # 新建一个空列表,用于存储文本
            for content in contents:
                text0 = content.xpath(".//text()").extract()  # 获取一个div里面的内容,为列表形式
                text0 = str(''.join(text0).strip())  # 合并列表为字符串,此为一个div里的文字内容
                text1.append(text0)  # 将该div里的文字内容(str)置于text1列表中
            text1 = str(''.join(text1).strip())  # 将获取所有div列表内容的text1列表转为合并的字符串,获得一个百度条目的所有内容
            item['text'] = text1  # 将该百度条目的内容置于item中
            url_set = set()  # 创建一个空集合
            for url_single in url_list:  # 遍历当前页面(百科条目)中所有的链接
                url_set.add(url_single.extract())  # 将所有链接置于该集合中
            valide_url = []
            for url in url_set:
                if self.shared_str in url:  # 判断该链接是否有“/item/”字符串
                    valide_url.append(self.base_url + url)  # True的话,置于列表中,该列表为我们所希望请求的有效url列表
            for url in valide_url:
                if creat_md5(url) not in self.set_stored:
                    self.set_stored.add(creat_md5(url))
                    yield Request(url=url, callback=self.parse, dont_filter=False)
                else:
                    logging.info('已经爬取过了')

        else:  # 如果请求失败,输出warning日志
            logging.warning("This url is not functional {}".format(response.url))
        yield item


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值