Spider-one

1. 爬虫是如何采集网页数据的:

  网页的三大特征:
  -1. 每个网页都有自己的 URL(统一资源定位符)地址来进行网络定位。
  -2. 每个网页都使用 HTML(超文本标记语言)来描述页面信息。
  -3. 网页都使用 HTTP(超文本传输协议)来传递 HTML数据。


爬虫的设计流程:
  -1. 爬虫通过网页的 URL地址,发送对应的HTTP请求给网站服务器。
  -2. 网站服务器返回对应的 HTTP 响应给爬虫,爬虫提取响应中的 HTML 数据内容。
  -3. 通过相关的HTML解析工具,提取HTML里的数据:
    -a. 如果是需要保存的目标数据,则根据需求保存数据(入库:txt、json、csv、mysql、redis、mongodb)
    -b. 如果是需要继续抓取的新的 URL地址,则从第一步重新开始执行。
  -4. 当所有的URL地址全部抓取完毕,程序结束。

  爬虫的主要两个瓶颈:硬件瓶颈(CPU、内存)、带宽瓶颈(网速)

    90%的网站没有反爬
    10%的网站有反爬

      -> 90%的反爬可以通过更改IP代理解决
      -> 10%的高级反爬:验证码、JS加密、动态渲染

  只要是用户可以访问的网络数据,爬虫都可以爬下来。


Baidu每天处理的用户数据量大约 20EB

1 bytes = 8 bit
1024 bytes = 1KB
1024 KB = 1 MB
1024 MB = 1 GB
1024 GB = 1 TB
1024 TB = 1 PB
1024 PB = 1 EB
1024 EB = 1 ZB

搜索引擎的排名算法:page rank(Google)、超链分析(Baidu)


2. 什么是字符编码?

  -1. 计算机里的所有数据,本质都是二进制数。

    二进制: 01100001
    十进制: 97
    十六进制: 61
    ASCII编码表: a


    1. ASCII 美国信息交换标准码,基于拉丁字母的一套电脑编码系统, 用来表示英文字母、数字和常用符号,总共 128 个字符(0~127)

    2. 后来计算机开始普及全球,每个国家都有自己的语言符号,ASCII 编码就不满足其他国家的需求。于是各个国家开始制定自己的编码(但是都是在 ASCII 基础上进行扩展)

      欧洲:Latin-1 ( 0~256)ISO-8859-1
      简体中文:gb2312->gbk->gb18030 (一个汉字占 2 个字节)
      繁体中文:Big5
      日文:Shift-JIS

    3. 编码不一致,导致文件交流不方便,为了解决整个问题,国际标准组织指定了一个编码:Unicode
      Unicode 又名万国码,包含了世界上所有国家的文字符号。但是有个缺点,浪费空间(汉字占4个字节等等)

    4. 于是在Unicode基础上进行了升级:utf-8(可变长的Unicode),可以根据文本类型指定不同的编码(在utf-8里一个汉字占 3 个字节,一个字母占 1 个字节),utf-8 是目前世界上最流行的编码。
      在所有的Linux系统终端默认编码,都是utf-8,90%以上的网页字符串,都是utf-8。


  -2 爬虫程序需要处理的编码场景:

    1. 发送请求获取网页响应(不同的网页有不同的编码)
    2. 数据处理过程中不同的字符串需要编码统一(编码要统一处理)
    3. 将处理结果保存起来(保存数据库、文件中要编码统一)

    如果编码不统一,会导致 "乱码"(按照其他编码表显示这个字符)


  -3. Python中如何处理字符串编码统一:

    1. Python3的字符串 类型和编码 对应:

      str 数据类型: Unicode 编码字符串
      bytes 数据类型: 非Unicode编码 字符串(其他编码字符串、图片音视频数据等)


    (了解)python2中的字符串类型和编码对应:
      unicode 数据类型: Unicode 字符串
      str 数据类型: 非Unicode字符串(其他编码字符串、图片音视频数据等)


3. 字符串如何转码(编码统一)

  口诀:任何操作系统的 任何编程语言 的任何编码,都可以和 Unicode互相转换。
  任何编码的字符串都可以解码为Unicode。再通过Unicode字符串转为其他编码

  gbk_str 转为 Unicode 转为 utf8_str:

  # 先将gbk字符串 通过 decode() 解码为 Unicode字符串
  unicode_str = gbk_str.decode("gbk")
  # 再将Unicode字符串 通过 encode() 编码为 utf-8字符串
  utf8_str = unicode_str.encode("utf-8")


4. 终端、代码中创建的字符串编码

  -1. Python3 和 iPython3 创建的字符串 是 Unicode 编码,str 类型的字符串。

  -2. Python2 根据使用的操作系统来定,Linux 是 utf-8、 简体中文Windows下是 GBK(可以通过 chcp 65001 修改为 utf-8)

    注意:在iPython2 下创建的字符串,默认全部都是 utf-8

  -3. print:字符串格式化输出函数,若将其他编码的字符串放入容器中输出时,不会进行解码


5. 将 Unicode 字符串数据保存在本地文件时

  Python3保存Unicode 字符串到本地文件时的编码,有三种处理方式:

    unicode_str = ""

    1. 直接保存Unicode字符串到本地文件时,解释器编码会参与工作:

      -1 Python3 默认的解释器编码是 utf-8,所以会把Unicode字符串按 utf-8 转码再保存文件,所以默认文件编码为 utf-8

        with open("test.txt", "w") as f:
          f.write(unicode_str)

      -2 Python2 默认的解释器编码是 ascii,所以会把Unicode字符串按 ascii 转码再保存文件(可能会导致 无法处理中文转码,导致报错: UnicodeEncodeError)
        查看解释器的默认编码: sys.getdefaultencoding()
        临时更改解释器编码 :
          import sys
          reload(sys)
          sys.setdefaultencoding("utf-8")

          with open("test.txt", "w") as f:
            f.write(unicode_str)


    2. 保存非 Unicode字符串到本地文件,手动对 Unicode字符串 进行转码再写入

      Python2 和 Python3 语法一致。
        with open("test.txt", "wb") as f:
          f.write(unicode_str.encode("utf-8"))
          #f.write(unicode_str.encode("gbk"))

        注: 写入文件时,禁止使用不同编码写入数据,会默认使用最后一次的编码格式,导致前面数据的不可逆的丢失。

 

    3. 通过 open() 的encoding 参数指定编码,再写入 Unicode字符串

      -1. Python3 的 open()方法 有 encoding 参数。

        with open("test.txt", "w", encoding="utf-8") as f:
          f.write(unicode_str)


      -2 Python2 的 open() 方法 没有 encoding参数,但是通过codecs模块的open方法,可以指定encoding参数。

        import codecs
        with codecs.open("test.txt", "w", encoding="utf-8") as f:
          f.write(unicode_str)

 

6. 文件编码注意
  文件当中没有 Unicode编码, 都是 utf-8编码, 当数据需要存储到文件当中时, 需要对其进行转码(例如: gbk 转码为 utf-8)

  当写入一个字符串到文件中时,文件编码 等于 该字符串编码。
  如果写入了不同 编码 到同一个文件中,会导致文件编码被修改为最后一次写入的字符串编码,同时导致之前的数据不可逆的丢失。


7. 网页编码
  /html/head/meta/charset 指定的,不同的网页编码类型可能不一样,会影响爬虫获取的数据编码。


8. 代码文件头部编码声明
  默认Python2的 代码文件头部编码声明是 ASCII,在python2的代码不能写非ASCII字符,否则会报错,所以需要提前加上下面这行代码。
  # -*- coding:utf-8 -*-

  Python 3默认的代码文件头部编码声明是 utf-8,无需手动修改。

 

10. 扩展点
Chrome抓包工具中获取的请求报头 快速转换字典:
匹配:''' ^(.*?):s(.*?)$ '''
替换:''' "1" : "2", '''


NetScape 网景 Mozilla 浏览器 -> Frame
Microsoft 微软 IE 1.0 浏览器 -> Frame 添加了Mozilla前缀

三流公司 做产品
二流公司 做设计
一流公司 做标准

Mozilla 基金会 Firefox 支持内核 Gecko
Linux 借鉴了Gecko-> KTHML 内核
Apple 借鉴了KHTML-> Webkit Safari
Google 借鉴了Webkit -> Chrome

 

11. 案例:百度贴吧页面分析

固定url地址部分: http://tieba.baidu.com/f?

表示贴吧名: kw=美食

百度贴吧页码值计算:
page =1 pn = 0
page =2 pn = 50
page =3 pn = 100

pn = (page - 1) * 50

 


12. 对于爬虫来说:网页通常分为两种 1. 静态页面; 2.动态页面

静态页面:数据内容直接保存在html中。
  url变化内容也会变化。

动态页面:数据不是直接保存在html里的,而是通过 ajax 请求获取数据再渲染的。
  url不变但内容会变化。
注意:动态页面必须要抓包,找到浏览器和服务器之间到底偷偷传递了什么文件。
动态页面由ajax进行动态请求数据,抓包时如果没有数据不会导致报错。 会返回一个空列表。

抓包:抓取网络数据包。

浏览器:第一次请求返回HTML,后续浏览器会自动尝试发送HTML中的CSS,js等其他请求,全部请求完成,再进行渲染。
爬虫: 一个请求对应一个文件,所有网站绝对支持HTTP,但不一定支持HTTPS

 

13. requests模块
  response.text: 会自动实现解码操作,但解码不一定成功。requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,所推测的文本编码不一定正确。
    修改解码方式: response.encoding = "gbk", 再使用 response.text 取出数据

  response.content: 获取到的是bytes类型的原始网页数据,还需要手动进行解码。【推荐】
    修改解码方式: response.content.decode("GBK"), 默认为 utf-8

  占位符: "{}".format(参数)

原文地址:https://www.cnblogs.com/hsmwlyl/p/10597996.html