从零开始的Python学习手记
python的语言格式什么的都不是问题,略过,主要麻烦在于建包之类的
情况:工作环境有限,无法访问许多外网,也没有IDE
目的:访问某网站提供信息并获取回复
原始基础代码:
# Get Token
import requests
tokenResponse = requests.get("http://aaa.com/getToken")
import json
jsonToken = json.loads(tokenResponse.text)
token = ""
if jsonToken["errorCode"] == 0:
token = jsonToken["source"]["token"]
pass
else : print(str(jsonToken["errorCode"])+":"+jsonToken["message"])问题1:Failed to establish a new connection: [Errno 11001] getaddrinfo failed
解决思路1:网站无法访问,需要代理,使用socket代理
——————
问题2:代理服务器需要用户名密码验证
解决思路2:使用Pysocks包进行验证
*无法连接外网下载Pysocks
在https://github.com/Anorov/PySocks下载后,使用python setup.py install安装
代码2:
import requests
import socket
import socks # pip install PySocks
socks.set_default_proxy(socks.SOCKS5,addr='xxx.xxx.xxx.xxx', port=xx, rdns=True/False, username='xxx', password='xxx')
socket.socket = socks.socksocket
sock = socket.socket()
sock.connect("http://aaa.com/getToken")
request = 'GET {} HTTP/1.0\r\nHost:aaa.com/getToken'.format('/s?wd={}'.format(wd))
response = b''
sock.send(request.encode())
response = sock.recv(40960)
print(response.decode())——————
问题3:PySocks doesn't support IPv6
经测试,并不是如错误信息的原因,而是sock.connect没有双层括号
代码3:
import socks
socks.set_default_proxy(socks.SOCKS5,[...])
sock = socks.socksocket()
url = "http://aa.com/getToken"
sock.connect((url,8080)) #必须要双层括号,且必须有端口号——————
问题4:Socket error: Connection closed unexpectedly
解决:修改为socks.HTTP
——————
问题5: encoding with 'idna' codec failed (UnicodeError: label too long)
解决:url过长,缩短就又回到连接问题了
*如果一直报[Errno 11001] getaddrinfo failed,考虑修改rdns连接方式,即proxy属性中True/False
——————
问题6:[*] Note: The HTTP proxy server may not be supported by PySocks (must be a CONNECT tunnel proxy)
经查代码,400, 403, 405这三种情况会报此错,我本次是400: Bad Request
可能性A:目标地址为HTTPS
可能性B:请求访问接口时传入的参数过大
可能性C:HttpGet或 HttpPost都不能传包含 ” 、“{“、”}”这样的参数,需要对特殊字符进行转义,把 ” 转成%22,把 { 转成%7b,把 } 转成%7d
可能性D:两个完全相同但是从属不同域的key=value段,放入请求中的cookie中,导致cookie过大
可能性E:前端提交数据的字段名称或者是字段类型和后台的实体类不一致,导致无法封装;
可能性F:前端提交的到后台的数据应该是json字符串类型,而前端没有将对象转化为字符串类型;
可能性G:URL是否“模糊匹配”
etc.
不同尝试如下:
10.27.*.*, 8080(本机Foreigh Address)
Socket error: 407: Unauthorized
10.24.*.*, 8080(本机Local Address)
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
10.24.*.*, 8080(老板给我的代理ip)
socks.HTTPError: 400: Bad Request
The HTTP proxy server may not be supported by PySocks (must be a CONNECT tunnel proxy)
***, 8080(netstat中端口号为8080的地址)
socks.HTTPError: 302: Found
***, 8080(乱填的地址)
socket.gaierror: [Errno 11001] getaddrinfo failed
10.24.*.*, 8080(同事的Local Address)
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond报错信息大全吗这里是?抓狂.gif
解决:目标网址,只能是Host!不带后续
*一个小tip,cmd中运行python程序卡住想要退出,又没有PauseBreak键,可以Fn+B
——————————
由此问题7:sendall后无反应
解决:
request = 'GET {} HTTP/1.0\r\nHost: xxx.com\r\n\r\n'.format('/aaa?bbb={}'.format(bbb))
sock.sendall(request.encode())要用这种格式
————————
问题8:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
解决:json格式不符
输出时容易漏看,实际获得的是这个:
“HTTP/1.1 200
Server: nginx
Date: Tue, 03 Mar 2020 09:30:10 GMT
Content-Type: application/json;charset=UTF-8
Connection: close
{"message":"AAA","status":200,"source":null}”
tokenResponse = str(sock.recv(4096),'utf-8')
import re
match = re.findall('\{.*?\}', tokenResponse)
print(match)
jsonToken = json.loads(match[0])——————————
齐活了!!
终于齐活了!!
yay!!!
代码对比:
初始:
# Get Token
import requests
tokenResponse = requests.get("http://aaa.com/getToken")
import json
jsonToken = json.loads(tokenResponse.text)
token = ""
if jsonToken["errorCode"] == 0:
token = jsonToken["source"]["token"]
pass
else : print(str(jsonToken["errorCode"])+":"+jsonToken["message"])最终:
import requests
import socks # pip install PySocks
import json
import re
#取得token
socks.set_default_proxy(socks.HTTP, "***.***.***.***", 8080, True, "username", "password")
sock = socks.socksocket()
url="aaa.com"
sock.connect((url,80))
#print("connected")
request = 'GET {} HTTP/1.0\r\nHost: aaa.com\r\n\r\n'.format('/getToken')
try:
print(request)
sock.sendall(request.encode())
except Exception as err:
print (err)
tokenResponse = str(sock.recv(4096),'utf-8')
match = re.findall('\{.*?\}', tokenResponse)
#print(match)
jsonToken = json.loads(match[0])
token = ""
if jsonToken["errorCode"] == 0:
token = jsonToken["source"]["token"]
pass
else : print(str(jsonToken["errorCode"])+":"+jsonToken["message"])