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(参数)
Spider-one的更多相关文章
- spider RPC入门指南
本部分将介绍使用spider RPC开发分布式应用的客户端和服务端. spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置 ...
- Scrapy:为spider指定pipeline
当一个Scrapy项目中有多个spider去爬取多个网站时,往往需要多个pipeline,这时就需要为每个spider指定其对应的pipeline. [通过程序来运行spider],可以通过修改配置s ...
- spider RPC过滤器
spider支持在请求执行前或完成后进行特殊处理,比如安全性检查.敏感字段混淆等等.为此,spider提供了BeforeFilter和AfterFilter.其执行位置如下图所示: 流水线插件配置在s ...
- spider RPC插件化体系
为了满足灵活扩展的需要,spider支持灵活的自定义插件扩展,从功能上来说,插件和过滤器的差别在于过滤器不会阻止请求的执行同时对于主程序不会有API上的影响(比如servlet 过滤器和监听器)(最多 ...
- spider RPC管理接口
为了在独立管理模式下尽可能的容易运行时排查问题,spider中间件提供了一系列restful api用于动态管理当前节点的路由,下游节点等.目前支持的RESTFUL API如下所示: 功能 服务号 R ...
- spider RPC高级特性
多租户 spider原生支持多租户部署,spider报文头对外开放了机构号.系统号两个属性用于支持多租户场景下的路由. 多租户场景下的路由可以支持下述几种模式: n 系统号: n 系统号+服务号( ...
- spider RPC安全性
spider提供了多重安全保障机制,目前主要支持接入握手校验,报文完整性校验,报文加密,报文长度检查四种机制. 接入认证 spider使用两次握手校验,其握手流程如下: 签名AES加密的方式实现. l ...
- spider RPC开发指南
协议与兼容性 spider使用java语言开发,使用Spring作为IoC容器,采用TCP/IP协议,在此基础上,结合SaaS系统模式的特性进行针对性和重点设计,以更加灵活和高效的满足多租户系统.高可 ...
- spider 配置文件参考
spider有一个配置文件spider.xml,为xml格式,spider.xml采用DTD进行管理,用于管理spider的所有特性.路由.高可用等. 配置文件支持三种不同的方式进行指定: 1. 通过 ...
- spider RPC性能测试报告
测试环境部署结构 测试用例 类 别 说明 请求报文 194字节({"systemId":"PL","appVersion":"qq ...
随机推荐
- iOS逆向之iOSOpenDev
上篇谈到使用TheOS进行越狱开发,但是流程相对而言较复杂,本篇我们谈一下iOSOpenDev进行越狱开发.通过使用iOSOpenDev,我们可以使用Xcode进行开发.编译.生成并运行到设备上. 1 ...
- org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.microsoft.sqlserver.jdbc.SQLServerDriver '
问题摘要: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nest ...
- docker 安装 RabbitMQ
1.镜像中国(http://www.docker-cn.com/registry-mirror):直接使用https://hub.docker.com下载镜像比较慢,使用镜像中国加速 使用例子:$ d ...
- MFS 服务扫描与爆破
MSF 服务发现 常用来发现局域网内,的常见服务,比如HTTP,FTP,TELNET等. MSF模块搜索: [root@localhost ~]# msfconsole msf5 > searc ...
- 47_并发编程-线程python实现
一.Threading模块 1.线程的创建 - 方式一 from threading import Thread import time def sayhi(name): time.sleep(2 ...
- GC垃圾回收机制,iOS内存管理。
问题: MRC中通过调用静态方法创建的新对象,不再使用时需要对其发送release消息吗? 不需要,因为约定静态方法创建的对象会自动将其放入自动释放池,即已对其发送autorelease消息,因此不可 ...
- 一篇入门 -- Git
一. Git 介绍 Git作为一款分布式的==版本控制==工具,作为一名程序员,是必须要掌握的. 最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布.最初目的是为更好地 ...
- python中除法的几种类型
传统除法:直接后缀小数点,同样结果是和最大的小数点对齐 >>> 1/2 0 >>> 1.0/2 0.5 >>> 1/2.0 0.5 >> ...
- js中break、continue和return的一般用法总结
break break :终止break的整个循环体,包括内部所有循环.但对循环体外部的循环不影响. for(let i = 0;i<2;i++){ for(let j = 0;j<2;j ...
- 【LeetCode】7. 整数反转
题目 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1:输入: 123 输出: 321 示例 2:输入: -123 输出: -321 示例 3:输入: 120 输出 ...