[英]How can I make sure a BS4 request is being made with a socket on a list?
我有一个这样的代理列表,我想在使用python进行爬取时使用:
proxies_ls = [ '149.56.89.166:3128',
'194.44.176.116:8080',
'14.203.99.67:8080',
'185.87.65.204:63909',
'103.206.161.234:63909',
'110.78.177.100:65103']
并制作了一个函数,以便使用bs4抓取网址并请求名为crawlSite(url)的模块。 这是代码:
# Bibliotecas para crawl e regex
from bs4 import BeautifulSoup
import requests
from fake_useragent import UserAgent
import re
#Biblioteca para data
import datetime
from time import gmtime, strftime
#Biblioteca para escrita dos logs
import os
import errno
#Biblioteca para delay aleatorio
import time
import random
print('BOT iniciado: '+ datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S'))
proxies_ls = [ '149.56.89.166:3128',
'194.44.176.116:8080',
'14.203.99.67:8080',
'185.87.65.204:63909',
'103.206.161.234:63909',
'110.78.177.100:65103']
def crawlSite(url):
#Chrome emulation
ua=UserAgent()
header={'user-agent':ua.chrome}
random.shuffle(proxies_ls)
#Random delay
print('antes do delay: '+ datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S'))
tempoRandom=random.randint(1,5)
time.sleep(tempoRandom)
try:
randProxy=random.choice(proxies_ls)
# Getting the webpage, creating a Response object emulated with chrome with a 30sec timeout.
response = requests.get(url,proxies = {'https':randProxy},headers=header,timeout=30)
print(response)
print('Resposta obtida: '+ datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S'))
#Avoid HTTP request errors
if response.status_code == 404:
raise ConnectionError("HTTP Response [404] - The requested resource could not be found")
elif response.status_code == 409:
raise ConnectionError("HTTP Response [409] - Possible Cloudflare DNS resolution error")
elif response.status_code == 403:
raise ConnectionError("HTTP Response [403] - Permission denied error")
elif response.status_code == 503:
raise ConnectionError("HTTP Response [503] - Service unavailable error")
print('RR Status {}'.format(response.status_code))
# Extracting the source code of the page.
data = response.text
except ConnectionError:
try:
proxies_ls.remove(randProxy)
except ValueError:
pass
randProxy=random.choice(proxies_ls)
return BeautifulSoup(data, 'lxml')
我想做的是确保仅在列表中使用该列表上的代理。 随机部分
randProxy=random.choice(proxies_ls)
工作正常,但检查代理是否有效的部分无效。 主要是因为我仍然收到200个“虚假代理”作为回应。
如果我将清单缩减为:
proxies_ls = ['149.56.89.166:3128']
使用不起作用的代理服务器,我仍然得到200作为响应! (我尝试使用https://pt.infobyip.com/proxychecker.php之类的proxychecker,它不起作用...)
所以我的问题是(我将列举出来,这样更容易):a)为什么我得到这个200的响应而不是一个4xx的响应? b)如何强制请求根据需要使用代理?
谢谢,
欧尼托
仔细阅读文档,您必须在字典中指定以下内容:
http://docs.python-requests.org/en/master/user/advanced/#proxies
“工作”字典应如下所示:
proxies = {
'https': 'socks5://localhost:9050'
}
这将仅代理和所有https请求。 这意味着它将不会代理http 。
因此,要代理所有webtraffic,您应该像下面这样配置dict:
proxies = {
'https': 'socks5://localhost:9050'
'http': 'socks5://localhost:9050'
}
当然,并在必要时替换IP地址。 有关其他情况,请参见以下示例:
$ python
>>> import requests
>>> proxies = {'https':'http://149.58.89.166:3128'}
>>> # Get a HTTP page (this goes around the proxy)
>>> response = requests.get("http://www.example.com/",proxies=proxies)
>>> response.status_code
200
>>> # Get a HTTPS page (so it goes through the proxy)
>>> response = requests.get("https://www.example.com/", proxies=proxies)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 485, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPSConnectionPool(host='www.example.com', port=443): Max retries exceeded with url: / (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f7d1f448c10>: Failed to establish a new connection: [Errno 110] Connection timed out',)))
因此,基本上,如果我对您的问题正确,那么您只想检查代理服务器是否有效。 requests
具有针对该requests
的异常处理程序,您可以执行以下操作:
from requests.exceptions import ProxyError
try:
response = requests.get(url,proxies = {'https':randProxy},headers=header,timeout=30)
except ProxyError:
# message proxy is invalid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.