第五十四课:论一只爬虫的自我修养:实战

内容来源于网络,本人只是在此稍作整理,如有涉及版权问题,归小甲鱼官方所有。

练习题(来自小甲鱼官方论坛)

0.请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!

  • 第一个例子是做一个最简单的爬虫
    我们去网站上下载一张图片。
import urllib.request

response = urllib.request.urlopen("http://placekitten.com/g/200/300")
cat_img = response.read()
with open('cat_200_300.jpg', 'wb') as f:
    f.write(cat_img)

req = urllib.request.Request("http://placekitten.com/g/200/400")
response2 = urllib.request.urlopen(req)
cat_img2 = response2.read()
with open('cat_200_400.jpg', 'wb') as f:
    f.write(cat_img2)

两张方法皆可。首先,urlopen的url参数既可以是一个字符串也可以是Request对象,如果你传入一个字符串,那么Python是会默认先帮你把目标字符串转换成Request对象,然后再传给urlopen函数。
然后,urlopen实际上返回的是一个类文件对象,因此你可以用read()方法来读取内容。除此之外,文档还告诉你有三个函数可能以后会用到:
1️⃣geturl():返回请求的url
2️⃣info():返回一个httplib.HTTPMessage对象,包含远程服务器返回的头信息
3️⃣getcode():返回HTTP状态码

import urllib.request

response = urllib.request.urlopen("http://placekitten.com/g/200/500")
print(response.geturl())
print(response.info())
print(response.getcode())

输出:

http://placekitten.com/g/200/500
Date: Tue, 28 Aug 2018 05:28:35 GMT
Content-Type: image/jpeg
Transfer-Encoding: chunked
Connection: close
Set-Cookie: __cfduid=d4759915be0d0d369ceb59fdfd4dcfcf71535434115; expires=Wed, 28-Aug-19 05:28:35 GMT; path=/; domain=.placekitten.com; HttpOnly
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=86400
Expires: Wed, 29 Aug 2018 05:28:35 GMT
CF-Cache-Status: HIT
Vary: Accept-Encoding
Server: cloudflare
CF-RAY: 45146018823196a0-FRA


200

  • 第二个例子是用有道来翻译文本。
    1️⃣首先打开官网http://fanyi.youdao.com
    第五十四课:论一只爬虫的自我修养:实战_第1张图片
    有道翻译.png

    2️⃣F12(或alt + command + i),切换到Network窗口。
    第五十四课:论一只爬虫的自我修养:实战_第2张图片
    Network.png

    3️⃣点击Method是POST的请求。
    第五十四课:论一只爬虫的自我修养:实战_第3张图片
    Headers.png

    HTTP是基于请求-响应的模式的,客户端发出的请求叫Request,服务端的响应叫Response。
    Request Headers是客户端发送请求的Headers,这个常常被服务器用来判断是否来自“非人类”的访问。例如写个Python代码,然后利用这个代码批量访问网站的数据,这样副武器的压力就会增大,所以一般服务器不欢迎“非人类”的访问。
    一般是通过这个User-Agent来识别,普通浏览器会通过该内容向访问网站提供你所使用的浏览器类型、操作系统、浏览器内核等信息的标识:
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
    而使用Python访问的话,User-Agent会被定义为Python-urllib/3.4。
    但事实上,User-Agent可以自定义的。
    第五十四课:论一只爬虫的自我修养:实战_第4张图片
    Form Data.png

    Form Data就是POST提交的内容。
    那么如何用Python提交POST表单呢?
    urlopen函数有一个data参数,如果给这个参数赋值,那么HTTP的请求就是使用POST方式;如果data=None,也就是默认值,那么HTTP的请求就是使用GET方式。
    第五十四课:论一只爬虫的自我修养:实战_第5张图片
    urllib.request.urlopen()提交数据.png

    这里还告诉我们,这个data参数的值必须符合这个application/x-www-form-urlencoded的格式,然后要用urllib.parse.urlencode()将字符串转换为这个格式。
import urllib.request
import urllib.parse

url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com"
data = {}
data['type'] = 'AUTO'

data['i'] = 'I love FishC.com!'
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['ue'] = 'UTF-8'
data['typoResult'] = 'true'
data = urllib.parse.urlencode(data).encode('utf-8')
response = urllib.request.urlopen(url, data)
html = response.read().decode('utf-8')
print(html)

输出:

{"type":"EN2ZH_CN","errorCode":0,"elapsedTime":0,"translateResult":[[{"src":"I love FishC.com!","tgt":"我爱FishC.com !"}]]}

字符串在Python3内部的表示是Unicode编码,因此,在做编码转换时,通常需要以Unicode作为中间编码,即先将返回的bytes对象的数据解码(decode)成Unicode,再从Unicode编码(encode)成另一种编码。
有关编码的问题可以参考https://fishc.com.cn/thread-56452-1-1.html。
接下来是解析上面这个JSON格式的字符串:

import urllib.request
import urllib.parse
import json

content = input("请输入需要翻译的内容:")
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com"
data = {}
data['type'] = 'AUTO'
data['i'] = content
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['ue'] = 'UTF-8'
data['typoResult'] = 'true'
data = urllib.parse.urlencode(data).encode('utf-8')  # 转换格式并编码为utf-8
response = urllib.request.urlopen(url, data)  # post请求必须带上data参数
html = response.read().decode('utf-8')
target = json.loads(html)
print("翻译结果:%s" % (target['translateResult'][0][0]['tgt']))  # 一层一层剥掉

输出:

请输入需要翻译的内容:I want to go home.
翻译结果:我想回家了。

  • 遇到{'errorCode': 50}怎么办?
    相信很多人玩小甲鱼的这个代码的时候都遇到了这个问题。
    注意有道的反爬虫机制。
    https://blog.csdn.net/nunchakushuang/article/details/75294947

你可能感兴趣的:(第五十四课:论一只爬虫的自我修养:实战)