1.urllib
- urllib 事实上是由两个单词组成的:URL(就是我们平时说的网页地址) 和 lib(就是library的意思,就是首页)
- 包含4个模块,request 、error、parse 和 robotparser
import urllib.request
response = urllib.request.urlopen("http://placekitten.com/500/600")
cat_img = response.read()
with open('cat_500_600.jpg', 'wb') as f:
f.write(cat_img)
- 客户端和服务器之间进行请求-响应时,最常用的是GET 和 POST两种方法
- urlopen 函数有一个 data 参数,如果给这个参数赋值,那么 HTTP 的请求就是使用 POST 方式;如果 data 的值是
None,也就是默认值,那么 HTTP 的请求就是使用 GET 方式
修改 headers 有两个途径:
- 通过 Request 的 headers 参数修改
- 通过 Request.add_header() 方法修改
import urllib.request
import urllib.parse
import json
content = input('请输入需要翻译的内容:')
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
#直接从审查元素中copy过来的url会报错,必须把translate_o中的_o 删除才可以
#这里就是把 Form Data 中的内容贴过来
data = {}
data['i'] = content
data['from'] = 'AUTO'
data['to'] = 'AUTO'
data['smartresult'] = 'dict'
data['client'] = 'fanyideskweb'
data['salt'] = '15445124815349'
data['sign'] = 'a824eba4c23c6f541ffadfee26b1e500'
data['ts'] = '1544512481534'
data['bv'] = 'bbb3ed55971873051bc2ff740579bb49'
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['action'] = 'FY_BY_REALTIME'
data['typoResult'] = 'false'
#需要使用urllib.parse.urlencode() 把data转换为需要的形式
data = urllib.parse.urlencode(data).encode('utf-8')
req = urllib.request.Request(url, data)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
response = urllib.request.urlopen(url, data)
html = response.read().decode('utf-8')
target = json.loads(html)
print('翻译结果:%s' %(target['translateResult'][0][0]['tgt']))
一个 IP 地址短时间内连续的进行访问,那么这是不符合正常人类的标准的,而且对服务器带来的压力不小,所以服务器合情合理会把你屏蔽掉
- 一种就是延迟提交的时间
- 一种就是使用代理 link
2.编码检测问题
import urllib.request
import chardet
def main():
url = input("请输入URL:")
response = urllib.request.urlopen(url)
html = response.read()
# 识别网页编码
encode = chardet.detect(html)['encoding']
if encode == 'GB2312':
encode = 'GBK'
print("该网页使用的编码是:%s" % encode)
if __name__ == "__main__":
main()
3.异常处理
- 先看有没有错误(包括URLError 和 HTTPError ),只要有 其中一个,就会打印 reason, 然后继续判断是否有 code ,如果有 code,就是 HTTPError ,然后也把 code 打印出来
>>> import urllib.request
>>> import urllib.error
>>> req = urllib.request.Request("http://www.fishc.com/ooxx.html")
>>> try:
urllib.request.urlopen(req)
except urllib.error.URLError as e:
if hasattr(e, 'reason'):
print('Reason: ', e.reason)
if hasattr(e, 'code'):
print('Error code: ', e.code)
Reason: Not Found
Error code: 404
4 re.findall()
import urllib.request
import re
def open_url(url):
req = urllib.request.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36')
response = urllib.request.urlopen(url)
html = response.read()
return html
def get_img(url):
html = open_url(url).decode('utf-8')
p = r'<img class="BDE_Image" src="([^"]+\.jpg)"'
imglist = re.findall(p, html)
for each in imglist:
filename = each.split('/')[-1]
urllib.request.urlretrieve(each, filename, None)
if __name__ == '__main__':
url = "https://tieba.baidu.com/p/4863860271"
get_img(url)
在 findall() 方法中,如果正则表达式包含着子组(即括号),那么就会把子组的内容单独给返回回来。如果存在多个子组,那么它还会将匹配的内容组合成元组的形式再返回。让子组不捕获内容,扩展语法就是非捕获组:
import urllib.request
import re
def open_url(url):
req = urllib.request.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36')
reponse = urllib.request.urlopen(req)
html = reponse.read()
return html
def get_ip(url):
html = open_url(url).decode('utf-8')
p = r'(?:(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])'
iplist = re.findall(p, html)
for each in iplist:
print(each)
if __name__ == "__main__":
url = "https://www.xicidaili.com/wt/"
get_ip(url)