从 url 派生协议

Derive protocol from url

我确实有一个 url 列表,例如 ["www.bol.com ","www.dopper.com"]format。 为了在 scrappy 上作为起始 URL 输入,我需要知道正确的 HTTP 协议。

例如:

["https://www.bol.com/nl/nl/", "https://dopper.com/nl"]

如您所见,协议可能从 httpshttp 甚至有或没有 www.

都不同

不确定是否还有其他变化。

  1. 是否有任何 python 工具可以确定正确的协议?
  2. 如果没有,我必须自己构建逻辑,我应该考虑哪些情况?

对于选项 2,这是我目前所掌握的:

def identify_protocol(url):
    try:
        r = requests.get("https://" + url + "/", timeout=10)
        return r.url, r.status_code
    except requests.HTTPError:
        r = requests.get("http//" + url + "/", timeout=10)
        return r.url, r.status_code
    except requests.HTTPError:
        r = requests.get("https//" + url.replace("www.","") + "/", timeout=10)
        return r.url, r.status_code
    except:
        return None, None

还有其他我应该考虑的可能性吗?

无法直接从片段中确定 protocol/full 域,信息根本不存在。为了找到它,您需要:

  1. 正确 protocol/domains 的数据库,您可以在其中查找您的域片段
  2. 发出请求并查看服务器告诉您的内容

如果您执行 (2),您当然可以逐步构建自己的数据库,以避免将来需要请求。

在许多 https 服务器上,如果您尝试使用 http 连接,您将被重定向到 https。如果不是,那么您可以可靠地使用 http.如果http失败了,你可以用https再试一下,看看能不能成功。

同样适用于域:如果站点通常重定向,您可以使用原始域执行请求并查看您被重定向到哪里。

使用 requests 的示例:

>>> import requests
>>> r = requests.get('http://bol.com')
>>> r
<Response [200]>
>>> r.url
'https://www.bol.com/nl/nl/'

如您所见,请求 对象url 参数具有最终目的地URL,加上协议。

据我了解,您需要在所有可能的重定向之后检索最终的 url。可以使用内置 urllib.request. If provided url has no scheme you can use http as default. To parse input url I used combination of urlsplit() and urlunsplit().

来完成

代码:

import urllib.request as request
import urllib.parse as parse

def find_redirect_location(url, proxy=None):
    parsed_url = parse.urlsplit(url.strip())
    url = parse.urlunsplit((
        parsed_url.scheme or "http",
        parsed_url.netloc or parsed_url.path,
        parsed_url.path.rstrip("/") + "/" if parsed_url.netloc else "/",
        parsed_url.query,
        parsed_url.fragment
    ))

    if proxy:
        handler = request.ProxyHandler(dict.fromkeys(("http", "https"), proxy))
        opener = request.build_opener(handler, request.ProxyBasicAuthHandler())
    else:
        opener = request.build_opener()

    with opener.open(url) as response:
        return response.url

然后你可以在列表中的每个 url 上调用这个函数:

urls = ["bol.com ","www.dopper.com", "https://google.com"]
final_urls = list(map(find_redirect_location, urls)) 

您也可以使用代理:

from itertools import cycle

urls = ["bol.com ","www.dopper.com", "https://google.com"]
proxies = ["http://localhost:8888"]
final_urls = list(map(find_redirect_location, urls, cycle(proxies)))

为了加快速度,您可以使用 ThreadPoolExecutor:

在并行线程中进行检查
from concurrent.futures import ThreadPoolExecutor

urls = ["bol.com ","www.dopper.com", "https://google.com"]
final_urls = list(ThreadPoolExecutor().map(find_redirect_location, urls))