scrapy(四)

Request

Scrapy.http.Resquest

  • Scrapy.http.Resquest类是scrapy框架中request的基类,它的参数如下:
    • url(字符串)-此请求的url
    • callback(callable)-回调函数
    • method(string)-此请求的http方法,默认为get
    • meta(dict)-Request.meta属性的初始值
    • body(str或Unicode)-请求体,如果没有传参,默认为空字符串
    • headers(dict)-此请求的请求头
    • cookies-请求cookie
    • encoding(字符串)-此请求的编码(默认为’utf-8)此编码将用于对url进行百分比编码并将body转换为str(如果给定Unicode)
    • priority(int)-此请求的优先级(默认为0)
    • dont_filter(boolean)-表示调度程序不应过滤此请求
    • errback(callable)-在处理请求时引发任何异常时将调用的函数
    • flags(list)-发送给请求的标志,可用于日志记录或类似的目的
      scrapy(四)_第1张图片

属性和方法

  • url包含此请求的url的字符串,该属性是只读的,更改请求使用的URL_replace()
  • method表示请求中的HTTP方法的字符串
  • headers类似字典的对象,包含请求头
  • body包含请求正文的str,该属性是只读的,更改请求使用的URL_replace()
  • meta包含此请求的任意元数据的字典
  • copy()返回一个新的请求,改请求是此请求的副本
  • replace([URL,method,headers,body,cookies,meta,encoding,dont_filter,callback,errback])返回一个更新对的request
    scrapy(四)_第2张图片

利用request.meta传递参数

FormRequest

  • get请求和post请求是最常见的请求,scrapy框架内置了一个FormRequest类
  • 它扩展了基类Request,具有处理HTML表单的功能
  • 它使用lxml.html表单,来预先填充表单字段,其中包含来自Response对象的表单数据
  • 具体API,学习源码

from_response()

  • 参数:
    • response(Responseobject)-包含HTML表单的响应
    • formname(string)-如果给定,将使用name属性设置为此值的表单
    • formid(string)-如果给定,将使用id属性设置为此值的表单
    • formxpath(string)-如果给定,将使用与xpath选择器匹配的第一个表单
    • formcss(string)-如果给定,将使用与css选择器匹配的第一个表单
    • formnumber(整数)-当响应包含多个表单时要使用的表单数
    • formdata(dict)-要在表单数据中覆盖的字段
    • clickdata(dict)-要用于查找单击控件的属性
    • don’t_click(boolean)-如果使用True,将提交表单数据而不单击任何元素

代码

  • 依旧是爬取腾讯招聘

      import scrapy
      from tencent.items import TencentItem
      from tencent.items import DetailItem
      from scrapy.http import Request,FormRequest
      class TencentRecruitSpider(scrapy.Spider):
          name = 'tencent_recruit'
          start_urls = ['https://hr.tencent.com/position.php']
          def parse(self, response):
              trs = response.xpath('//table[@class="tablelist"]/tr[@class="even"]|//table[@class="tablelist"]/tr[@class="odd"]')
              if trs:     #如果没有表示到了最后一页
                  for tr in trs:
                      item = TencentItem()
                      item['job_name'] = tr.xpath('./td[1]/a/text()').extract_first()
                      item['job_type'] = tr.xpath('./td[2]/text()').extract_first()
                      item['job_num'] = tr.xpath('./td[3]/text()').extract_first()
                      item['job_addr'] = tr.xpath('./td[4]/text()').extract_first()
                      item['job_time'] = tr.xpath('./td[5]/text()').extract_first()
                      url = tr.xpath('./td[1]/a/@href').extract_first()
                      yield response.follow(
                          url=url,
                          meta={'job_item':item}, #会把item和request绑到一起
                          #放入request中会传递到当前request请求回来的response中
                          callback=self.parse_detail
                      )
                  next_url = response.xpath('//a[@id="next"]/@href').extract_first()  # 如果有多个值,用extract
                  req = scrapy.Request('https://hr.tencent.com/%s' % next_url)
                  yield req
              else:
                  return
          def parse_detail(self, response):
              item = response.meta['job_item']
              item['job_detail'] = "".join(response.xpath('//ul[@class="squareli"]/li/text()').extract())
              yield item
    

豆瓣登录

import scrapy
import json
class LoginSpider(scrapy.Spider):
    name = 'login'
    allowed_domains = ['douban.com']
    start_urls = ['https://douban.com/']
    login_urls = 'https://accounts.douban.com/j/mobile/login/basic'
    def parse(self, response):
        form_data = {
            'ck': '',
            'name': '11111111111',
            'password': '22222222',
            'remember': 'false',
            'ticket': '',
        }
        yield scrapy.FormRequest(url=self.login_urls, formdata=form_data, callback=self.login_after)
    def login_after(self, response):
        res = json.loads(response.body.decode('utf-8'))
        if res['status']=='success':
            print('登录成功!当前账户为:%s' % res['payload']['account_info']['name'])
        else:
            print('登录失败')

Response

  • 参数:
    • url(字符串)-此响应的url
    • status(整数)-响应的http状态,默认为200
    • headers(dict)-此响应的响应头,dict值可以是字符串(对于单值标头)或列表(对于多值标头)
    • body(字节)-响应主体,要将解码后的文本作为str(Python 2中的Unicode)访问,可以使用response.text来自编码感知的Response子类,例如TextResponse
    • flags(列表)-是包含Response.flags属性初始值的列表,如果给定,列表将被浅层复制
    • request(Requestobject)-Response.request属性的初始值,这表示Request生成此响应的内容
    • response.属性
  • 属性和方法
    • url
    • status
    • headers
    • body
    • request
    • meta 来自于request
    • flags
    • copy() 返回新的response
    • replace([url,status,headers,body,request,flags,cls]),更改url
    • urljoin(url) 在url后面拼接
    • follow(url),自动拼接域名,添加头

日志配置和使用

  • 日志在代码迭代和更新上起调试作用

在spider中记录

  • Scrapy logger在每个Spider实例中提供了一个可以访问和使用的实例
  • 使用方法见下图
    scrapy(四)_第3张图片

在其他组件中记录

  • 可以通过Python的logging来记录
  • 比如:logging.warning(‘This is a warning!’)
  • 但是为了后期维护方面,我们可以创建不同的记录器来封装消息,并且使用组件或函数的名称进行命名
    scrapy(四)_第4张图片

配置

  • 这些设置可用于配置日志记录
    • LOG_FILE 日志输出文件,如果为None,就打印在控制台
    • LOG_ENABLED 是否使用日志,默认True
    • LOG_ENCODING 日志编码,默认utf-8
    • LOG_LEVEL 日志等级,默认debug
    • LOG_FORMAT 日志格式
    • LOG_DATEFORMAT 日志日期格式
    • LOG_STDOUT 日志标准输出,默认False,如果True所有标准输出都将写入日志中
    • LOG_SHORT_NAMES 短日志名,默认为False,如果True将不输出组件名
    • 项目中一般设置:
    • LOG_FILE = ‘logfile_name’
    • LOG_LEVEL = 'INFO’
      scrapy(四)_第5张图片

你可能感兴趣的:(爬虫)