使用urllib2可以对URL请求进行抽象.这样您就可以在实际发出请求之前对请求主体执行操作.
像这样的东西,例如:
def authentication(self, req):
signup = md5(str(req.get_data())).hexdigest()
req.add_header('Authorization', signup)
return urllib2.urlopen(req)
def some_request(self):
url = 'http://something'
req = urllib2.Request(url)
response = authentication(req)
return json.loads(response.read())
Run Code Online (Sandbox Code Playgroud)
我想使用python-requests而不是urllib2.我怎样才能实现上面使用它的例子呢?
我使用Python请求来获取图像,但在某些情况下,sit不起作用.它似乎经常发生.一个例子是
它在我的浏览器中正常加载,但是使用请求时,它会返回显示"403 forbidden"和"nginx/1.7.11"的html
import requests
image_url = "<the_url>"
headers = {'User-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Encoding':'gzip,deflate,sdch'}
r = requests.get(image_url, headers=headers)
# r.content is html '403 forbidden', not an image
Run Code Online (Sandbox Code Playgroud)
我也试过这个标题,在某些情况下这是必要的.结果相同.
headers = {'User-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36', 'Accept':'image/webp,*/*;q=0.8','Accept-Encoding':'gzip,deflate,sdch'}
Run Code Online (Sandbox Code Playgroud)
(几周前我有一个类似的问题,但PIL不支持特定的图像文件类型.这是不同的.)
编辑:基于评论:
看来该链接仅在您访问过原始网站http://aussietaste.recipes/vegetables/leek-vegetables/leek-and-sweet-potato-gratin/时才有效.我想浏览器然后使用缓存版本.任何解决方法?
我目前使用它来连接socks5代理和paramiko.
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5,socks_hostname,socks_port, True, socks_username,socks_password)
paramiko.client.socket.socket = socks.socksocket
ssh = paramiko.SSHClient()
Run Code Online (Sandbox Code Playgroud)
但是,我希望在python中使用requesocks和paramiko的相同代理设置进行一些请求,并且找不到任何关于用户名和密码的内容.
此外,所有请求每次都使用不同的socks连接完成,全局设置可能会妨碍我的其他连接.
关于如何做到或有替代方法的任何想法?我当前的实现非常严重地使用python请求所以从那里转换到requesocks会很好,所以我不必重构所有内容.
注意:如何通过socks代理使python请求工作不起作用,因为它不使用socks5身份验证.
我已编写代码来从网站获取表格,但我需要通过以下方式访问其他表格:
该网站是:
http://www.myfxbook.com/forex-market/currencies/nzdchf-historical-data
下拉列表上的Inspect元素显示:
<select id="timeScales" class="selectField" onfocus="borderChange(this); "onblur="borderReturn(this);" style="border: 1px solid rgb(226, 225, 225);">
<option id="timeScale1" value="1">1 Minute</option>
<option id="timeScale5" value="5">5 Minutes</option>
<option id="timeScale15" value="15">15 Minutes</option>
<option id="timeScale30" value="30">30 Minutes</option>
<option id="timeScale60" value="60">1 Hour</option>
<option id="timeScale240" value="240">4 Hours</option>
<option id="timeScale1440" value="1440" selected="">1 Day</option>
<option id="timeScale10080" value="10080">1 Week</option>
<option id="timeScale43200" value="43200">1 Month</option>
Run Code Online (Sandbox Code Playgroud)
从时间范围下拉列表中,我想选择4个小时,然后单击过滤器按钮.
我知道如何使用requests.get方法获取HTML,但我遇到的问题是当我选择下拉值时URL不会改变.
我尝试过使用requests.post,但我显然不知道如何使用它.我正在编写这个程序使用"如何自动使用PYTHON的镗孔"作为教程,作者没有解释如何以编程方式单击下拉菜单和单击按钮.
他确实解释了Selenium的使用,但我必须重复这个过程超过30次,每次打开一个新页面需要太长时间.
如果您能够展示如何使用请求模块(如果可能)实现这一点,我将不胜感激.
我对python-requests模块有疑问。根据文档
多亏了urllib3,保持活动状态在会话中是100%自动的!您在会话中发出的任何请求都将自动重用适当的连接!
我的示例代码如下所示:
def make_double_get_request():
response = requests.get(url=API_URL, headers=headers, timeout=10)
print response.text
response = requests.get(url=API_URL, headers=headers, timeout=10)
print response.text
Run Code Online (Sandbox Code Playgroud)
但是我收到的日志告诉我们,每个请求都会启动新的HTTP连接:
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): url
DEBUG:requests.packages.urllib3.connectionpool:"GET url HTTP/1.1" 200 None
response text goes here
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): url
DEBUG:requests.packages.urllib3.connectionpool:"GET url HTTP/1.1" 200 None
response text goes here
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?通过查看带有Wireshark的数据包,似乎实际上它们已经设置了保持活动状态。
例如我的代码是:
import requests
r = requests.get('https://www.python.org')
r.status_code
Run Code Online (Sandbox Code Playgroud)
结果是:
Traceback (most recent call last):
File "C:\Users\Till\workspace\firstproject\Learning_python\Web_crawler.py", line 6, in <module>
import requests
File "C:\Python32\lib\site-packages\requests\__init__.py", line 64, in <module>
from .models import Request, Response, PreparedRequest
File "C:\Python32\lib\site-packages\requests\models.py", line 856
http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
^
SyntaxError: invalid Syntax
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用来检查过期的域名python-requests。
import requests
try:
status = requests.head('http://wowsucherror')
except requests.ConnectionError as exc:
print(exc)
Run Code Online (Sandbox Code Playgroud)
这段代码看起来太通用了。它产生以下输出:
HTTPConnectionPool(host ='wowsucherror',port = 80):URL超过最大重试次数:/(由NewConnectionError(':未能建立新连接:[Errno 11001] getaddrinfo失败',))
我想做的是仅捕获此DNS错误(例如ERR_NAME_NOT_RESOLVED在Chrome中)。作为最后的选择,我只能进行字符串匹配,但是也许有更好,更结构化和前向兼容的方式来处理此错误?
理想情况下,它应该是的DNSError扩展requests。
更新:Linux上的错误有所不同。
HTTPConnectionPool(host ='wowsucherror',port = 80):URL超过最大重试次数:/(由NewConnectionError(':导致无法建立新连接:[Errno -2]名称或服务未知',))
将错误报告给requests-> urllib3 https://github.com/shazow/urllib3/issues/1003
UPDATE2:OS X也报告不同的错误。
requests.exceptions.ConnectionError:HTTPConnectionPool(host ='wowsucherror',端口= 80):url超过了最大重试次数:/(由NewConnectionError(':导致:无法建立新连接:[Errno 8]节点名或服务名未提供,或未知',))
我在用r = requests.post(something).我期待json被退回.看着r.headers我回来了'Content-Type': 'application/json' and 'Content-Encoding': 'gzip'.
当我表演的时候,json.loads(r.text)我期待的是一个对象,dict但是,<class 'list'>
不知道为什么这不会创造一个字典?
返回的数据如下所示:
[{'contentId': '0ee022728af31b01', 'creationTS': 1484778192149,
'updateTS': 1484778192188, 'lastUser': 'cmmigration', 'mimeType':
'application/pdf', 'sourcePath': None, 'effectiveTS': None,
'softDeleteTS': None, 'contentFileName': '[DRAFT] (null).pdf',
'applicationId': 'ICX', 'currentState': 1, 'applicationName': 'ICX',
'versionNum': 1, 'chronicleId': '0ee022728af31b00', 'expirationTS':
1650030026000, 'versionLabel': 'WIP', 'contentFilePath':
'/PO/2015/03/13/49412051/', 'lockDate': None, 'encryptedFlag': False,
'authorId': 'migration', 'solrACLList': None, 'customAttributes':
'{"r_object_id":"097b4c76800e5d55","icon_view_allow":"SP","subject":"Icon"
,"icon_pvendor":620418,"r_creation_date":"2015-04-17T09:40:28","ic_store_num":"xxxx","ic_mvendor":50031248,"ic_oded":"0","ic_upd_user_id":"txrxxx","icon_src_system":"I2GO","isanned":"0","icon_po_lead_date":"2015-04-13T20:35:06","language_code":"en_US","ic_user_id":"txrxxx","r_modify_date":"2015-04-17T09:40:29","i_po_num":"49412051","icon_bus_doc":750,"i_indexed":"0","icon_lead_num":"-1"}', 'softDeleteFlag': False, 'lockFlag': False, 'archiveTS': None, 'lockId': None, 'fileSize': 223062}]</pre>
Run Code Online (Sandbox Code Playgroud) 我想确保在使用请求库发布到HTTP服务器时,它会拒绝使用TLSv1或TLSv1.1进行通信.为此,我配置了我的https服务器以强制SSL协议使用TLSv1或TLSv1.1.我希望这些版本被拒绝.
我的python程序在CentOs机器上运行:
cat /etc/centos-release
CentOS release 6.7 (Final)
Run Code Online (Sandbox Code Playgroud)
默认的Python版本是2.6.6:
which python
/usr/bin/python
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2
Run Code Online (Sandbox Code Playgroud)
我安装了python 2.7:
which python2.7
/usr/local/bin/python2.7
Python 2.7.6 (default, Jun 2 2017, 11:37:31)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-16)] on linux2
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.1e-fips 11 Feb 2013'
openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
Run Code Online (Sandbox Code Playgroud)
使用pip2.7,我安装了所需的库以获取运行请求.我没有对openssl做任何改动.
我发送了两个测试警报,似乎我的程序协商到TLSv1.我的印象是TLSv1已被弃用.该程序使用python 2.7执行,而不是python 2.6的系统默认值.
在我嵌入的python程序的顶部:#!/ usr/local/bin/python2.7
以下是显示TLSv1.1和TLSv1的2个帖子警报:
"POST /testpost HTTP/1.1" 200 43 TLSv1.1/ECDHE-RSA-AES256-SHA "-" "python-requests/2.5.1 CPython/2.6.6 …Run Code Online (Sandbox Code Playgroud) x = [10,20,30]
for i in x:
print(i)
x.append(40)
x = [50,60]
print(x)
Run Code Online (Sandbox Code Playgroud)
输出为:
10
20
30
40
[50,60]
Run Code Online (Sandbox Code Playgroud)
为什么20、30、40来?不是50,60
python-requests ×10
python ×8
dns ×1
http ×1
image ×1
json ×1
keep-alive ×1
pyopenssl ×1
python-3.x ×1
socks ×1
tls1.2 ×1