• python爬虫笔记


    4、urllib库
      模拟浏览器发送请求的库,Python自带
      Python2: urllib urllib2
      Python3: urllib.request urllib.parse

      字符串==》字节类型之间的转化
      encode() 字符串==》字节类型
      如果小括号里面不写参数,默认是utf8
      如果写,就写gbk
      decode() 字节类型==》字符串
      如果不写 默认utf8
      如果写,就写gbk
      urllib.request
        urlopen(url)
        urlretrieve(url,image_path)
        urllib.parse
        quote(url) url编码函数,将中文进行转化为%xxx;注意,发请求的url不能包含中文和特殊字符,所以有特殊字符和中文则需要用此函数编码
        unquite(url) url解密函数,将%xxx转化成相应字符串
        urlencode(url) 将一个字典拼接为query_string,并且实现了编码的功能
      response
        read() 读取相应内容,内容是字节类型
        geturl() 获取请求的url
        getheaders() 获取头部信息,列表里面有元组
        getcode() 获取状态码
        readlines() 按行读取,法规列表,都是字节类型

    5、get方式
      构建请求头部信息(这是反爬的第一步)
      a)伪装自己的UA,让服务端认为你是浏览器在上网
      b)构建请求对象 urllib.request.Request(url=url,headers=headers)
      c)ssl._create_default_https_context = ssl._create_unverified_context # 取消ssl验证
    6、post方式
      1.【注】表单数据的处理
        urllib.parse.urlencode(form_data).encode()
        fidder抓包,一个本上面有个箭头,代表就是post请求
    '    Accept-Encoding': 'gzip, deflate, br', # 此句不需要加
    7、ajax
    8、URLErrorHTTPError
      这两个类都在urllib.error模块中
      NameError TypeError FileNotFound 异常
      异常处理,结构 try-except
      URLError:
        (1)没有网
        (2)服务器连接失败(域名不存在)
        (3)找不到指定的服务器
      HTTPError:
        是URLError的子类
        【注】两个同时捕获的时候,需要将HTTPError写到上面,HTTPError写在下面
    9、Handler处理器、自定义Opener
      a)urlopen() 给个url,发送请求,获取响应
      b)Request() 定制请求头,创建请求对象
    10、高级功能:使用代理,cookie
      基本用法:
      a)代理
        1、代理是什么?
        2、生活中的代理:微商、代练
        3、程序中的代理:
          正向代理:代理客户端获取数据
          反向代理:代理服务端提供数据
        4、配置:
          浏览器配置
          代码代理
            handler = urllib.request.ProxyHandler({'http':'116.209.58.148:9999'})
            opener = urllib.request.build_opener(handler)
          后续都使用opener.open方法去发送请求即可
      b)cookie
        1、cookie是什么?
        2、http协议,无状态
        3、登录网站时候的问题,用来记录用户身份的
        模拟登录:

    # 创建一个cookiejar对象
    cj = http.cookiejar.CookieJar()
    # 通过cookiejar创建一个handlder
    handler = urllib.request.HTTPCookieProcessor(cj)
    # 通过handler 创建一个opner
    opener = urllib.request.build_opener(handler)

        再往下所有的操作都是用opener.open方法发送请求,因为这里面带着cookie过去了
    11、正则表达式解析:
      a)单字符:
        . : 除换行符以外所有字符
        [] : [aoe] [a-w] 匹配集合中的任意一个字符
        d : 非数字
        w : 数字、字母、下划线、中文
        W : 非w
        s : 所有的空白字符
        S : 非空白
      b)数量修饰:
        * :任意多次 >=0
        + : 至少一次 >=1
        ? : 可有可无 0次或者1次
        {m} : 固定m次
        {m,} : 至少m次
        {m,n} : m-n次
      c)边界:
         B
        $ : 以某某结尾
        ^ : 以某某开头
      d)分组:
        (ab){3}
        (){4} 视为一个整体
        () 子模式组模式 1 2
      e)贪婪模式:
        .*? .+? # 加?取消贪婪
        re.I : 忽略大小写
        re.M : 多行匹配
        re.S : 单行匹配(多行变单行)

        matchsearchfindall
        re.sub(正则表达式,替换内容,字符粗)
    12、bs4(BeautifulSoup)
      a)需要将pip源设置为国内源
        Windows:
        (1)打开文件资源管理器
        (2)地址栏上面输入%appdata%
        (3)在这里面 新建一个文件夹pip
        (4)在pip文件夹里面新建一个文件叫做 pip.ini,内容如下即可

    [global]
    timeout = 6000
    index-url = https://mirrors,aliyun.com/pypi/simple/
    trusted-host = mirrors.aliyun.com

        Linux:
        (1)cd ~
        (2)mkdir ~/.pip
        (3)vi ~/.pip/pip.conf
        (4)编辑内容,和windows一样
        (2)需要安装:pip install bs4
      b)bs4在使用时候需要一个第三方库lxml(pip install lxml)
      c)简单使用:
        1、说明:选择器
        2、导入:from bs4 import BeautifulSoup
        3、使用方式:可以将一个html文档,转换成指定的对象,然后通过对象的方法或者属性去查找指定的内容
        4、转化本地文件:

    soup = BeautifulSoup(open('本地文件'),'lxml')

        5、转化网络文件:

    soup = BeautifulSoup('字符串类型/字节类型','lxml')

        6、使用方法:

          1)根据标签名查找
            soup.a 只能找到第一个符合要求的标签
          2)获取属性
            soup.a.attrs 获取所以的属性和值,返回一个字典
            soup.a['title'],soup.a.attrs['title'] 两个等价

          3)获取内容
            soup.a.text:都能获取
            soup.a.string:只能是文本,如果标签里有标签的话,获取None
            soup.a.get_text():都能获取
          4)find(找到的都是第一个符合要求的节点)
            soup.find('a') 找到第一个符合要求的a标签
            soup.find('a',title='qing')
            soup.find('a',class_='aaa') # 注意class是关键字要用class_
            soup.find('div',class_='song').find('p',class_='li') 可以连缀查找
          5)find_all (返回所有符合要求的节点)
            soup.find_all('a','b') # 支持同时查找多标签
            soup.find_all('a',limit=2) # 支持查找数据量
          6)select
            根据选择器选择指定的内容
            常见选择器:标签选择器、类选择器、id选择器、组合选择器、层级选择器、伪类选择器、属性选择器
            select 选择器返回永远是列表,该方法也可以通过普通对象调用
    13、xpath
      a)什么是xpath?
        xml是用来存储和传输数据
      b)和html的不同的两点:
        1)html用来显示数据,xml是用来传输数据
        2)html标签是固定的,xml标签是自定义的
      c)xpath用来在xml中查找指定的元素,它是一种路径表达式

        常用的路径表达式:
          // : 从不考虑位置的查找
          ./ : 从当前节点开始往下查找
          @ : 选取属性

      实例:

    /bookstore/book 选取根节点bookstore下面所有直接子节点book
    //book 选取所有book
    bookstore//book 查找bookstore下面所有的book
    /bookstore/book[1] bookstore里面的第一个book
    /bookstore/book[last()] bookstore里面的最后一个book
    /bookstore/book[position()<3] 选取bookstore里面的前两个book
    //title[@lang] 选取所有拥有lang属性的tittle
    //title[@lang='eng'] 选取所有拥有lang属性值为eng的title

          * :匹配任何元素节点

      d)安装xpath插件
        1、将xpath插件拖动到谷歌浏览器扩展程序中
        2、启动和关闭插件
        3、ctrl + shift + x
      e)属性定位
        //input[@id="wk"]
        //input[@class="bg s_btn"] # 多个class是个整体,不可拆分查找
      f)层级定位
      h)索引定位
        //div[@id="head"]/div/div[2]/a[@class="toindex"]
        【注】索引从1开始
        //div[@id="head"]//a[@class="toindex"]
        【注】双斜杠代表下面所有的a节点,不管位置
      i)逻辑运算
        //input[@class="s_ipt" and @name="wd"]
      j)模糊匹配【】

        1、contains
          //input[contains(@class,"s_i")]
          所有的input,有class属性,并且class中包含s_i
          //input[contains(text(),"爱")]
        2、starts-with
          //input[contains(@class,"s")]
          所有的input,有class属性,并且class中必须以s开头
      k)取文本
        

    //div[@id="u1"]/a[5]/text()
    //div[@id="u1"]//text() 获取节点里面不带标签的所有内容
    string = ret[0].xpath('string(.)') # 直接将内容拼接起来返回
    print(string.replace('
    ','').replace('	','').replace(' ',''))

      m)取属性
        //div[@id="u1"]/a[5]/@href
        代码里使用xpath
        导入库:from lxml import etree
        两种方式使用:将html文档变成一个对象,然后调用对象的方法查找指定的节点
          1、本地文件
            tree = etree.parse(文件名,etree.HTMLParser(encoding="utf-8"))
          2、网络文件
            tree = etree.HTML(网页字符串)
          3、换行问题:
            a)存储的时候显示的 是有效的
            b)在读取过来单独使用的时候换行符生效'
    14、图片加载问题
      a)懒加载技术:用到的时候加载
        实现方式:

    <img src2="图片路径"> 加载时变为下面格式
    <img src="图片路径">

    15、jsonpath
      jsonpath:用来解析json数据使用的
      python处理json格式用到的函数
      使用:import json
        json.dumps():将字典或者列表转化为json格式的字符串
        json.loads():将json字符串转化为Python对象
        json.dump():将字典或者列表转化为json格式字符串并且写入到文件中
        json.load():从文件中读取json格式字符串,转换为Python对象
      安装:
        pip install lxml
        pip install jsonpath
      用法:
        jsonpath用一个抽象的名字$来表示最外层对象。
        xpath的表达式:/store/book[1]/title
        jsonpath的表达式:x.store.book[0].title
        或 x['store']['book'][0]['title']

      xpath 和 jsonpath对比:
        / $ 表示跟元素
        . @ 当前元素
        / . 子元素
        // .. 任意位置查找
        * * 通配符
        [] ?() 过滤
        xpath 索引下标从1开始
        jsonpath 索引下标从0开始
    16、selenium和PhantomJS
      1、selenium是什么?
        python的第三方库,对外提供接口可以操作你的浏览器,然后让浏览器自动化的操作
      2、使用selenium
        安装:pip install selenium
        操作谷歌浏览器,首先必须有谷歌浏览器的一个驱动
        谷歌驱动下载地址
          http://chromedriver.storage.googleapis.com/index.html
        谷歌驱动和谷歌浏览器版本关系映射表
          https://blog.csdn.net/huilan_same/article/details/51896672
      3、代码操作

    from selenium import webdriver
    browser = webdriver.Chrome(path)
    browser.get()

      4、使用下面方法,找到指定的元素进行操作即可

    find_element_by_id 根据id找节点
    find_element_by_name 根据name找
    find_element_by_xpath 根据xpath查找
    find_element_by_tag_name 根据标签名找
    find_element_by_class_name 根据class名字查找
    find_element_by_css_selector 根据选择器查找
    find_element_by_link_text 根据链接内容查找
    getsend_keysclick

      5、PhantomJS
        a、是什么?是一款浏览器,无界面浏览器
        b、selenium+phantomjs 就是爬虫终极解决方案
          1、下拉滚动条到底部
          2、豆瓣电影下拉
          3、图片懒加载
          4、获取网页的代码:browser.page_source
    17、Headless Chrome
      1、无头谷歌浏览器,无界面谷歌浏览器
      2、因为phantomjs现在都不维护了
      3、mac、linux,版本号59+以上,才支持这种模式
      4、windows,要求版本号的60+以上,才支持这种模式
      5、使用

    from selenium.webdriver.chrome.options import Options
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')

    18、requests
      安装:pip install requests
      官方文档:
        http://cn.python-requests.org/zh_CN/latest/
      用来做什么?
        和urllib是同一个为位置的,是对urllib的封装,底层是urllib3
      get请求
        定制头部
          data:是一个原生字典
          requests.get(url,headers=headers,params=data)
        响应对象
          r.text 字符串形式查看响应
          r.content 字节类型查看响应
          r.encoding 查看或者设置编码类型
          r.status_code 查看状态码
          r.headers 查看响应头部
          r.url 查看所请求的url

      post请求
        必应翻译
          formdata:是一个原生字典
          r = requests.post(url,headers=headers,data=formdata)
      ajax、get、post
        和上面一样
        代理
          r = requests.get(url=url,headers=headers,params=data,proxies=proxies)
        cookie
          s = requests.Session()
          r = s.get(url=url,headers=headers,params=data,proxies=proxies)
        chinaunix
          登录思路:先get,再post,再get
    19、验证码
      a)tesseract简介
        光学识别,只能识别简单的验证码
        代码测试:pip install pytesseract pillow
      b)打码平台
        打码兔、云打码
    23、线程回顾
      a、引入
        多任务,多个任务同时进行,多进程,多线程
        多进程:sublime、录屏、vnc服务器
        多线程:word(包括编辑,查看等线程同时执行)
      b、创建线程Thread
        1、面向过程:
          tsing = threading.Thread(target=sing,name='sing',args=(a, ))
          target:线程启动之后要执行的函数
          name:线程的名字
          获取线程名字:threading.current_thread().name
          # 启动线程
          tsing.start()
          # 让主线程等待子线程结束之后再结束
          tsing.join()
          # 这里是主线程
          print('这里是主线程')
        2、面向对象
          定义一个类,继承自threading.Thread,重写一个方法run方法,
          需要主线程名字、传递参数,重写构造方法,在重写构造方法的时候,
          一定要注意手动调用父类的构造方法。
        3、线程同步
          线程之间共享全局变量,很容易发生数据混乱问题,
          这个时候要使用线程锁,抢,谁抢到,谁上锁之后,谁就先用
        4、创建锁
            suo = threading.lock()
          上锁
            suo.acquire()
          释放锁
            suo.release()
        5、队列(queue)
          a)下载线程
            //解析线程,通过队列进行交互
            q = Queue(5)
            q.put('xxx') 如果队满,程序卡在这里等待
            q.put('xxx',False) 如果队满,程序直接报错
            q.put('xxx',True,3) 如果队列满,程序等待3s再报错

          b)获取数据
            print(q.get()) 如果队列为空,程序卡在这里等待
            print(q.get(False)) 如果队列为空,程序直接报错
            print(q.get(True,3)) 如果队列为空,程序等待3s报错

          c)q.empty() 判断队列是否为空
          d)q.full 判断队列是否已满
          e)q.qsize 判断队列长度

    24、多线程爬虫
      分析:
        两类线程:下载(3)、解析线程(3)
        内容队列:下载线程往队列中put数据,解析线程从队列get数据
        url队列:下载线程从url队列get数据
        写数据:上锁

  • 相关阅读:
    【我读cachecloud】cachecloud-open-web模块controller
    【我读cachecloud】cachecloud项目概述
    [转]Kerberos协议
    【shell】我的wait为什么不能用
    【 一次性密码】TOTP
    【shell】再看一眼find--find使用中遇到的问题分析
    我知道点redis-单机数据库(RDB持久化)
    我知道点redis-数据结构与对象(对象)-对象实现
    我知道点redis-数据结构与对象(对象)-对象存储
    我知道点redis-数据结构与对象(链表)
  • 原文地址:https://www.cnblogs.com/liugp/p/10562708.html
Copyright © 2020-2023  润新知