• 网络爬虫(12)-Scrapy框架Post请求发送


    1.递归爬取解析多页页面数据

    - 需求:将糗事百科所有页码的作者和段子内容数据进行爬取切持久化存储

    - 需求分析:每一个页面对应一个url,则scrapy工程需要对每一个页码对应的url依次发起请求,然后通过对应的解析方法进行作者和段子内容的解析。

    实现方案:

    • 将每一个页码对应的url存放到爬虫文件的起始url列表(start_urls)中。(不推荐)
    • 使用Request方法手动发起请求。(推荐)
    # -*- coding: utf-8 -*-
    import scrapy
    from qiushibaike.items import QiushibaikeItem
    # scrapy.http import Request
    class QiushiSpider(scrapy.Spider):
        name = 'qiushi'
        allowed_domains = ['www.qiushibaike.com']
        start_urls = ['https://www.qiushibaike.com/text/']
    
        #爬取多页
        pageNum = 1 #起始页码
        url = 'https://www.qiushibaike.com/text/page/%s/' #每页的url
    
        def parse(self, response):
            div_list=response.xpath('//*[@id="content-left"]/div')
            for div in div_list:
                #//*[@id="qiushi_tag_120996995"]/div[1]/a[2]/h2
                author=div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first()
                author=author.strip('
    ')
                content=div.xpath('.//div[@class="content"]/span/text()').extract_first()
                content=content.strip('
    ')
                item=QiushibaikeItem()
                item['author']=author
                item['content']=content
    
                yield item #提交item到管道进行持久化
    
             #爬取所有页码数据
            if self.pageNum <= 13: #一共爬取13页(共13页)
                self.pageNum += 1
                url = format(self.url % self.pageNum)
    
                #递归爬取数据:callback参数的值为回调函数(将url请求后,得到的相应数据继续进行parse解析),递归调用parse函数
                yield scrapy.Request(url=url,callback=self.parse)

    2.post请求发送

    - 问题:在之前代码中,我们从来没有手动的对start_urls列表中存储的起始url进行过请求的发送,但是起始url的确是进行了请求的发送,那这是如何实现的呢?

    - 解答:其实是因为爬虫文件中的爬虫类继承到了Spider父类中的start_requests(self)这个方法,该方法就可以对start_urls列表中的url发起请求:

    def start_requests(self):
        for u in self.start_urls:
            yield scrapy.Request(url=u,callback=self.parse)

    【注意】该方法默认的实现,是对起始的url发起get请求,如果想发起post请求,则需要子类重写该方法。

    -方法: 重写start_requests方法,让其发起post请求:

    def start_requests(self):
        #请求的url
        post_url = 'http://fanyi.baidu.com/sug'
        # post请求参数
        formdata = {
            'kw': 'wolf',
        }
        # 发送post请求
        yield scrapy.FormRequest(url=post_url, formdata=formdata, callback=self.parse)

    3.如何提高scrapy的爬取效率

    增加并发:
    - 默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。

    降低日志级别:
    - 在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’

    禁止cookie:
    - 如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False

    禁止重试:
    - 对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False

    减少下载超时:
    - 如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

  • 相关阅读:
    hdu 2586 How far away ?
    zoj 3195 Design the city
    hust 1022 K-diff subsequence
    poj 2253 Frogger
    poj 1470 Closest Common Ancestors
    poj 2553 The Bottom of a Graph
    poj 1236 Network of Schools
    poj 3694 Network
    uva 10131 Is Bigger Smarter ? (简单dp 最长上升子序列变形 路径输出)
    2014年百度之星程序设计大赛
  • 原文地址:https://www.cnblogs.com/Iceredtea/p/11909337.html
Copyright © 2020-2023  润新知