一.scrapy分页处理

  1.分页处理

  1.   如上篇博客,初步使用了scrapy框架了,但是只能爬取一页,或者手动的把要爬取的网址手动添加到start_url中,太麻烦
    接下来介绍该如何去处理分页,手动发起分页请求
  2.  
  3. 爬虫文件.py
  1. # -*- coding: utf-8 -*-
    import scrapy
    from qiubaiPage.items import QiubaiproItem
  2.  
  3. class QiubaiSpider(scrapy.Spider):
    name = 'qiubai'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.qiushibaike.com/text/']
    url='https://www.qiushibaike.com/text/page/%d/'
    page_num=1
  4.  
  5. # 2.基于管道的持久化存储(基于管道的持久化存储必须写下管道文件当中)
    def parse(self,response):
    div_list=response.xpath('//div[@id="content-left"]/div')
    for div in div_list:
    try :
    author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
  6.  
  7. except Exception as e:
    print(e)
    continue
    content = div.xpath('./a[1]/div/span//text()').extract()
    content = ''.join(content)
  8.  
  9. # 实例话一个item对象(容器)
    item = QiubaiproItem()
    item['author'] = author
    item['content'] = content
    # 返回给pipline去持久化存储
    yield item
  10.  
  11. if self.page_num<10: #发起请求的条件
    self.page_num+=1
    url=(self.url%self.page_num)
    #手动发起请求,调用parse再去解析
    yield scrapy.Request(url=url,callback=self.parse)
  12.  
  13. items.py
  1. import scrapy
    class QiubaiproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author=scrapy.Field()
    content=scrapy.Field()
  1. pipline.py
  1. class QiubaipagePipeline(object):
    f = None
  2.  
  3. # 开启爬虫时执行程序执行一次,重写父类的方法,可以开启数据库等,要记得参数有一个spider不要忘记了
    def open_spider(self, spider):
    self.f = open('./qiushibaike.txt', 'w', encoding='utf-8')
  4.  
  5. # 提取处理数据(保存数据)
    def process_item(self, item, spider):
    self.f.write(item['author'] + ':' + item['content'] + '\n')
    return item
  6.  
  7. # .关闭爬虫时执行也是只执行一次,重写父类方法,可以关闭数据库等,重写父类要要有参数spider,不要忘记了
    def colse_spider(self, spider):
    self.f.close()
  8.  
  9. 注意:要基于管道存储要记得去settings.py把注释放开

  

  2.post请求

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

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

  

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

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

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

  3.cookies处理

  1.   对于cookies的处理就是不用处理,直接去settings.pycookies的相关配置放开就行

  4.请求传参之中间件代理池使用

一.下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件。

- 作用:

(1)引擎将请求传递给下载器过程中, 下载中间件可以对请求进行一系列处理。比如设置请求的 User-Agent,设置代理等

(2)在下载器完成将Response传递给引擎中,下载中间件可以对响应进行一系列处理。比如进行gzip解压等。

我们主要使用下载中间件处理请求,一般会对请求设置随机的User-Agent ,设置随机的代理。目的在于防止爬取网站的反爬虫策略。

二.UA池:User-Agent池

- 作用:尽可能多的将scrapy工程中的请求伪装成不同类型的浏览器身份。

- 操作流程:

1.在下载中间件中拦截请求

2.将拦截到的请求的请求头信息中的UA进行篡改伪装

3.在配置文件中开启下载中间件

  1.  
     请求传参的使用:首先要你要明白整个scrapy模块的使用流程:在下载器和引擎之间有个下载中间件,他可以拦截到所有的请求对象和所有的响应对象,包括异常的请求和异常的响应.
    这就我们提供了便利-------->使用袋里池--------->把请求对象兰拦截下来,给他换一个ip地址,再把请求对象向网络发布出去!
      还有一个要注意的是要去settings.py文件中把中间件相关的配置放开
  2.  
  3. middleware.py  
    #下载中间件class QiubaipageDownloaderMiddleware(object): # Not all methods need to be defined. If a method is not defined,
  1. # scrapy acts as if the downloader middleware does not modify the
    # passed objects.
  2. @classmethod
    def from_crawler(cls, crawler):
    # This method is used by Scrapy to create your spiders.
    s = cls()
    crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
    return s
      #拦截请求
    def process_request(self, request, spider):

      request.meta['proxy'] = 'https://60.251.156.116:8080'
      print('this is process_request!!!')

  1. # Called for each request that goes through the downloader
    # middleware.
  2.  
  3. # Must either:
    # - return None: continue processing this request
    # - or return a Response object
    # - or return a Request object
    # - or raise IgnoreRequest: process_exception() methods of
    # installed downloader middleware will be called
    return None
      #拦截响应
    def process_response(self, request, response, spider):
    # Called with the response returned from the downloader.
  4.  
  5. # Must either;
    # - return a Response object
    # - return a Request object
    # - or raise IgnoreRequest
    return response
      #拦截异常
    def process_exception(self, request, exception, spider):
    # Called when a download handler or a process_request()
    # (from other downloader middleware) raises an exception.
  6.  
  7. # Must either:
    # - return None: continue processing this exception
    # - return a Response object: stops process_exception() chain
    # - return a Request object: stops process_exception() chain

      request.meta['proxy'] = 'https://60.251.156.116:8080' #可以把多个代理封装成列表对象,请求时随机抽出一个来形成一个代理池
      print('this is process_exception!!!')

 

  5.请求传参之递归请求网页数据

  在某些情况下,我们爬取的数据不在同一个页面中,例如,我们爬取一个电影网站,电影的名称,评分在一级页面,而要爬取的其他电影详情在其二级子页面中。

这时我们就需要用到请求传参。

  1. 爬虫文件.py
  2.  
  3. # -*- coding: utf-8 -*-
  4. import scrapy
  5. from bossPro.items import BossproItem
  6.  
  7. class BossSpider(scrapy.Spider):
  8. name = 'boss'
  9. # allowed_domains = ['www.xxx.com']
  10. start_urls = [
  11. 'https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&scity=101280600&industry=&position=']
  12.  
  13. def parse(self, response):
  14. li_list = response.xpath('//div[@class="job-list"]/ul/li')
  15. for li in li_list:
  16. job_title = li.xpath('.//div[@class="job-title"]/text()').extract_first()
  17. company = li.xpath('.//div[@class="company-text"]/h3/a/text()').extract_first()
  18. #那子网页url
  19. detail_url = 'https://www.zhipin.com' + li.xpath('.//div[@class="info-primary"]/h3/a/@href').extract_first()
  20. # detail_url = 'https://www.zhipin.com' + li.xpath('.//div[@class="info-primary"]/h3/a/@href').extract_first()
  21. # 实例化一个item对象
  22. item = BossproItem()
  23. item["job_title"] = job_title
  24. item['company'] = company
  25. # 把item传给下一个解析函数,请求传参
  26. yield scrapy.Request(url=detail_url, callback=self.detail_parse, meta={'item': item})
  27. #二级网页解析
  28. #要通过以及解析把item传过来我才能把数据装到容器里面
  29. def detail_parse(self, response):
  30. item = response.meta["item"]
  31. job_detail= response.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div//text()').extract()
  32. job_detail=''.join(job_detail)
  33. item['job_detail']=job_detail
  34. #记得要返回,要不然pipline拿不到东西
  35. yield item
  36.  
  37. settings.py
  38.  
  39. #robts协议
    #pipiline
    #ua
    都要设置好
  40.  
  41. items.py
  1. import scrapy
    class BossproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    job_title=scrapy.Field()
    company= scrapy.Field()
    job_detail = scrapy.Field()
  2.  

scrapy模块之分页处理,post请求,cookies处理,请求传参的更多相关文章

  1. vue.js学习之 跨域请求代理与axios传参

    vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...

  2. 使用Fiddler工具发送post请求(带有json数据)以及get请求(Header方式传参)

    Fiddler工具是一个http协议调试代理工具,它可以帮助程序员测试或调试程序,辅助web开发. Fiddler工具可以发送向服务端发送特定的HTTP请求以及接受服务器回应的请求和数据,是web调试 ...

  3. Laravel请求/Cookies/文件上传

    一.HTTP请求 1.基本示例:通过依赖注入获取当前 HTTP 请求实例,应该在控制器的构造函数或方法中对Illuminate\Http\Request 类进行类型提示,当前请求实例会被服务容器自动注 ...

  4. SpringMVC——接收请求参数和页面传参

    Spring接收请求参数: 1.使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(Ht ...

  5. SpringMVC之接收请求参数和页面传参

    1.Spring接收请求参数 1>.使用HttpServletRequest获取 @RequestMapping("/login.do") public String log ...

  6. .NET CORE API 使用Postman中Post请求获取不到传参问题

    开发中遇到个坑 记录下. 使用Postman请求core api 接口时,按之前的使用方法(form-data , x-www-form-urlencoded)怎么设置都无法访问. 最后采用raw写入 ...

  7. SpringMVC接收请求参数和页面传参

    接收请求参数: 1,使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(HttpServ ...

  8. jmeter处理http请求Content-Type类型和传参方式

    引言 我们在做接口测试的时候经常会忽略数据类型content-type的格式,以及参数Parameters和Body Data的区别和用途. 对于初次接触接口的同学来说,自己在发送一个http请求时, ...

  9. Spring Cloud feign GET请求无法用实体传参的解决方法

    代码如下: @FeignClient(name = "eureka-client", fallbackFactory = FallBack.class, decode404 = t ...

随机推荐

  1. .net中对HTTP请求的两种请求:Get和Post的操作

    .net中对HTTP请求的简单操作总结 第一部分,HTTP协议的简单了解 一.           什么是HTTP协议 超文本传输协议 (HTTP-Hypertext transfer protoco ...

  2. what is diff. b/w app state & session state

    Application state is a data repository available to all classes in an ASP.NET application. Applicati ...

  3. css总结7:盒子模型理解

    1 盒子模型 1.1盒子模型的盒子:     以博客园页面为例: 1.2盒子内部构造:边框(border).内容(content).填充(padding).边界(margin)---CSS盒子模式都具 ...

  4. backquote

    character (`) A backquote or backtick. echo 'date' date echo `date` 2015年 07月 03日 星期五 16:11:13 CST j ...

  5. Linq 左连接 left join

    Suppose you have a tblRoom and tblUserInfo. Now, you need to select all the rooms regardless of whet ...

  6. java实现链式队列

    java实现链式队列...比较简单 package datastruct; public class QueueLink implements Queue { // 定义一个节点内部类 class N ...

  7. wp socket tcp链接

    using System; using System.Net; /// <summary> /// 客户端通过TCP/IP连接服务端的方法,包含连接,发送数据,接收数据功能 /// < ...

  8. .Net Core 项目引用本地类库方式(二)

    上篇文章有详细的介绍.Net Core 项目中引用本地类库通过打包,然后Nugety引用方式,这里再介绍一种引用包的方式

  9. mybatis 学习笔记(三):mapper 代理开发 dao 层

    mybatis 学习笔记(三):mapper 代理开发 dao 层 优势 通过使用mapper 代理,我们可以不需要去编写具体的实现类(使用 getMapper() 方法自动生成),只需编写接口即可, ...

  10. 「BZOJ1433」[ZJOI2009] 假期的宿舍(二分图,网络流)

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...