zoukankan      html  css  js  c++  java
  • 爬虫笔记

    xpath 工具,获取HTML元素

    节点修饰符

    / 根节点,(最外层元素标签)

    // 子节点(相对路劲)

    . 当前路径

    .. 上一次路径

    @xx 获取节点的属性

    text() 获取值

    包含语法(contains),包含部分就能够查找所有 //div[contains(@id,"qiushi_tag_")] (糗事百科)

    数据解析方法

    主要有结构化和非结构化分类

    结构化:

    ​ json数据(高拼出现)

    ​ json 模块

    ​ re 模块

    ​ jsonpath模块

    ​ xml 数据 (低频出现)

    ​ re 模块

    ​ lxml 模块

    非结构化

    ​ html

    ​ re 模块

    ​ lxml模块

    服务器反爬的原因

    1 爬虫占的PV(页面的访问次数, 每打开刷新一个页面的话,就占一个pv)总数较高,浪费资源

    2 三月爬虫 , 毕业生在写论文的时候,会进行爬取一些网站数据,在进行分析

    3 法律的灰色地带

    爬虫反反爬机制

    1 设置 headers 请求头(异步请求等) 和 设置 referew字段(从哪来发起的请求)

    2 通过cookie来进行反爬

    3 通过请求的参数来进行反爬

    ​ 1根据html文件提取

    ​ 2 通过发送请求获取数据

    ​ 3 通过js来生成参数 (分析js,通过js2py获取js执行结果,或使用selenium)

    ​ 4 验证码 (打码平台)

    4 更换ip代理

    scrapy 框架

    • 1 scrapy 框架 是python开源 编写一个网络爬虫框架

    网络爬虫的流程

    image-20200719213943828

    流程:

    1 首先我们有起始的url

    ​ 2 拿到起始的url后放到URL队列,从队列中拿到URL发送网络请求获取响应

    ​ 3 拿到请求响应后进行 解析响应内容,如果解析的是数据,那么将数据保存, 如果解析的 是url的话 返回给url队列,进行一个循环操作

    scrapy 框架工作流程

    image-20200719220248584

    简易理解

    image-20200719214344254

    工作流程步骤:

    ​ 1首先拿到起始的url 通过 scrapy 引擎(中间件)传递 到url队列中

    ​ 2 从url 队列 拿出起始的url 给 发送请求获取响应(下载器), 得到响应对象之后 通过 scrapy 引擎 (中间件)传递给解析响应对象

    ​ 3 解析响应对象,如果解析出新的URL对象之后 会再次给 url队列中,如果解析的是数据的 话 会拿给 scrapy 引擎(中间件)item poplin (管道)做 数据的保存或过滤

    抽象讲 scrapy 工作原理

    image-20200719220248584

    image-20200719221915624

    scrapy Engine (引擎)负责调度 各种模块的运行

    Scheduler(调度器)接收引擎发送过来的request请求

    spiders (爬虫) 负责处理解析出所有的数据和url,并将解析到新的URL提交给引擎,再次进入Scheduler(调度器)

    Downloader (下载器)接收scrapy引擎发送过来的 url 进行发送请求获取响应

    item pipeline (管道)负责处理 spiders 发送的过来的数据,进行保存。

    scrapy 中每个模块的作用

    image-20200719222413933

    创建项目

    image-20200720092205172

    创建爬虫项目

    scrapy startproject [项目名]

    创建爬虫

    cd 进入 爬虫项目

    scrapy genspider [爬虫名字] [域名]

    运行爬虫命令

    scrapy crawl [爬虫名字]

    定义元素以及提取数据,属性值的方法

    从xpath 对象中提取数据 extract() 和 extract_first()

    解析response并获取scrapy爬虫中的数据: 利用xpath规则字符串进行定位和提取

    response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法

    提取数据:

    ​ 额外方法extract():返回一个包含有字符串的列表

    ​ 额外方法extract_first():返回列表中的第一个字符串,列表为空没有返回None

    response响应对象的常用属性:

    ​ response.url:当前响应的url地址

    ​ response.request.url:当前响应对应的请求的url地址

    ​ response.headers:响应头

    ​ response.request.headers:当前响应的请求头

    ​ response.body:响应体,也就是html代码,byte类型

    ​ response.status:响应状态码

    注意: 如果要存储数据的话,需要通过pipeline来保存数据。

    函数中的yield能够传递的对象只能是:BaseItem, Request, dict, None

    2 建模 可以通过items.py中建立所需的字段。然后在spider 中调用在使用.

    3 meta:实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等

    在爬虫文件的parse方法中,提取详情页增加之前callback指定的parse_detail函数:

    def parse(self,response):
        ...
        yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})
    ...
    
    def parse_detail(self,response):
        #获取之前传入的item
        item = resposne.meta["item"]
    

    特别注意

    1. meta参数是一个字典
    2. meta字典中有一个固定的键proxy,表示代理ip,关于代理ip的使用我们将在scrapy的下载中间件的学习中进行介绍

    scrape 获取cookie模拟登陆

    第一种方法,使用的是直接获取cookie登录

    第二种方法 通过scrapy.FormRequest能够发送post请求,同时需要添加fromdata参数作为请求体,以及callback

    # 模拟登陆 GitHub,使用的是scrapy框架
    import re
    
    import scrapy
    
    
    class GithubSpider(scrapy.Spider):
        name = 'github'
        allowed_domains = ['github.com']
        start_urls = ['http://github.com/login']
    
        # tARzc847MynkgK1DIeayOZMQHNNN22tj0usmHmGy4BjZ0gvpjWfxDefFqqf9BL9pgKGwJq2DTUHZG6itMmxdMA==
        def parse(self, response):
            token = response.xpath("//*[@id='login']/form/input[1]/@value").extract_first()
            # 获取登录响应解析post的数据
            data = {
                "commit": "Sign in",
                "authenticity_token": token,
                "login": "xiaohua439912875",
                "password": "kongguanghua520",
                "webauthn-support": "supported"
            }
    
            # 2 根据url进行post请求
            yield scrapy.FormRequest(
                url="http://github.com/session",
                formdata=data,
                callback=self.parse_login
            )
    
        def parse_login(self, response):
            match = re.search(r'"user-login" content="(.*?)"', response.text)
            user_name = match.group(1)
            print('UserName:', user_name)
    
    
  • 相关阅读:
    Chip Factory(HDU5536 + 暴力 || 01字典树)
    Xor Sum(HDU4825 + 字典树)
    Happy Matt Friends(HDU5119 + dp)
    Intersection(HDU5120 + 圆交面积)
    [iOS Animation]-CALayer 绘图效率
    [iOS Animation]-CALayer 性能优化
    [iOS Animation]-CALayer 定时器动画
    [iOS Animation]-CALayer 缓冲
    [iOS Animation]CALayer-图层时间
    [iOS Animation]-CALayer 显示动画
  • 原文地址:https://www.cnblogs.com/kongguanghua/p/13570538.html
Copyright © 2011-2022 走看看