爬虫(Py2和Py3区别)

什么是字符编码?

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

二进制 0b01100001 十进制 97 通过 ASCII编码表 对应字符 ‘a’

简体中文: gb2312、gbk、gb18030, cp936 ,code page 936,一个汉字2个字节
繁体中文: Big5
日文:Shift-jis
诞生了 Unicode编码,包含了世界上所有国家的字符,对编码进行了大一统。 每个字符占用 3~6 个字节,浪费空间。

诞生了 utf-8 可变长的Unicode,一个汉字占3个字节,一个字母占1个字节,大大了减少了空间占用。

爬虫程序处理编码的场景:

  1. 发送请求获取网页内容(不同的网页编码可能不一样)
  2. 程序处理时产生的字符串(可能会有不同编码)
  3. 保存结果需要统一编码(写入保存时候的编码)

二、Python2和Python3的 字符编码 和 字符类型

Python3:
Unicode字符串 str 类型
非Unicode字符串 bytes 类型

Python2:
Unicode字符串 unicode 类型
非Unicode字符串 str 类型

三、编码的转换

任何语言、任何平台、任何编码的字符串,都可以和Unicode互相转换。

例 : utf8_str -> gbk_str

非Unicode字符串,可以通过decode解码为Unicode字符串
unicode_str = utf8_str.decode(“utf-8”)
# Unicode字符串, 可以通过 encode 编码为其他编码
gbk_str = unicode_str.encode(“gbk”)

反之: gbk_str -> utf8_str
unicode_str = gbk_str.decode(“gbk”)
utf8_str = unicode_str.encode(“utf-8”)

UnicodeDecodeError、UnicodeEncodeError

四、终端创建字符串的编码
在解释器终端创建的字符串
Python2:根据操作系统决定
Linux为utf-8、简体简体中文Windows 为 gbk。注意,如果是iPython创建的,都是 utf-8
Python3:Unicode 编码

五、文件编码
写入字符串到文件中,文件创建成功,则文件编码等同于写入的字符串编码。

如果写入了其他编码的字符串,则文件编码被修改,原来的内容会变成"乱码"。

六、处理字符串写入文件时候的编码。

Python不能直接写 Unicode字符串到文件中,必须写入 非Unicode

1. 手动转码处理

    Python3:
        # w 必须写 Unicode, wb 写非Unicode(gbk、utf-8、jpg、mp4)
        with open("xxx.txt", "wb") as f:
            f.write(unicode_str.encode("utf-8"))

    Python2:
        # w 写字符串, wb 写非字符串
        with open("xxx.txt", "w") as f:
            f.write(unicode_str.encode("utf-8"))


2. 通过 open()方法的 encoding 参数

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

    Python2:
        Python2的 open() 没有 encoding,但是可以通过 codecs 模块解决

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


3. 如果强行写入Unicode字符串,且并没有通过 1 和 2 处理,则Python解释器编码尝试转码再写入。

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

    Python2 默认解释器编码是 ascii,在处理中文则报错 UnicodeEncodeError 无法按 ASCII编码处理中文字符串,

        解决方案,将Python2 解释器编码修改为 utf-8

        import sys
        reload(sys)
        sys.setdefaultencoding("utf-8")


    Python3 默认解释器编码是 utf-8,不会出现任何错误

七、代码文件头部编码声明
Python2 默认代码文件编码声明是 ascii,所以代码中有中文部分会报错,
解决方案,在代码第一行添加

#coding:utf-8

Python3 默认代码文件编码声明是 utf-8,所以不需要修改。

八、urlencode编码

import urllib
qeryt_str = urllib.urlencode({“wd” : “你好”})

https://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD&pn=40

爬虫三大池:UserAgent池、IP代理池、Cookie池

练习

第一种方法:

#coding:utf-8

import random
import urllib
import urllib2

USER_AGENT_LIST = [
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
]
def send():
		# 通过random.choice随机从列表中返回一个新的useragent
		useragent = random.choice(USER_AGENT_LIST)
		headers = {'User-Agent':useragent}
		# 构建一个包含请求报头的请求对象
		request = urllib2.Request("http://www.baidu.com/", headers=headers)
	    # 发送指定的url地址请求,返回一个类文件的响应对象
	    response = urllib2.urlopen(request)
	
	    # 获取响应的状态码
	    if response.getcode() == 200:
	    # 读取响应中内容,获取网页原始编码字符串
	        	html = response.read()
	    	    return html
	    return None
if __name__ == '__main__':
    html = send_request()
    with open("baidu.html", "w") as f:
        f.write(html)

第二种方法:

#coding:utf-8

import random
import urllib2

USER_AGENT_LIST = [
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
]

def send_request():

    # UserAgent池、IP代理池、Cookie池
    # 通过random.choice随机从列表中返回一个新的useragent
    useragent = random.choice(USER_AGENT_LIST)

    # 构建一个包含请求报头的请求对象
    request = urllib2.Request("http://www.baidu.com/")

    # 添加/修改 指定请求报头值
    request.add_header("User-Agent", useragent)

    # 获取指定请求报头值,注意a必须小写
    print(request.get_header("User-agent"))

    # 发送指定的url地址请求,返回一个类文件的响应对象
    response = urllib2.urlopen(request)

    # 获取响应的状态码
    if response.getcode() == 200:
        # 读取响应中内容,获取网页原始编码字符串
        html = response.read()
        return html
    return None

if __name__ == '__main__':
    html = send_request()
    with open("baidu.html", "w") as f:
        f.write(html)

4、构建字典查询

#coding:utf-8


import urllib
import urllib2

def send_request():
    #输入自定义查询的关键字
    keyword = raw_input("请输入需要查询的关键字")
    # 固定的url地址
    base_url = "https://www.baidu.com/s?"

    # 构建查询字典
    query_dict = {"wd" : keyword, 'pn':'40'}
    # 通过urlencode方法,构建查询字符串
    query_str = urllib.urlencode(query_dict)

    # 和固定的url地址拼接,构建完整的url地址
    full_url = base_url + query_str

    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"}
    reqeust = urllib2.Request(full_url, headers=headers)

    response = urllib2.urlopen(reqeust)

    return response.read()

if __name__ == '__main__':
    html = send_request()
    with open("baidu.html", "w") as f:
        f.write(html)

Python3代码:

#coding:utf-8

# import urllib
# import urllib2

import urllib.request
import urllib.parse

def send_request():
    #输入自定义查询的关键字
    keyword = input("请输入需要查询的关键字")
    # 固定的url地址
    base_url = "https://www.baidu.com/s?"

    # 构建查询字典
    query_dict = {"wd" : keyword}

    ########1.  通过urlencode方法,构建查询字符串
    ########query_str = urllib.urlencode(query_dict)
    query_str = urllib.parse.urlencode(query_dict)


    # 和固定的url地址拼接,构建完整的url地址
    full_url = base_url + query_str

    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"}

    ######### 2. 构建请求
    #reqeust = urllib2.Request(full_url, headers=headers)
    reqeust = urllib.request.Request(full_url, headers=headers)

    ######### 3. 发送请求,返回响应
    #response = urllib2.urlopen(reqeust)
    response = urllib.request.urlopen(reqeust)

    return response.read()
    
if __name__ == '__main__':
    html = send_request()
    with open("baidu.html", "wb") as f:
        f.write(html)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值