如何用 Python 编写 Web 代理

2024-02-10

我正在尝试用 python 编写一个网络代理。目标是访问如下网址:http://proxyurl/http://anothersite.com/并查看内容http://anothersite.com就像平常一样。通过滥用 requests 库,我已经取得了相当大的进展,但这并不是 requests 框架的真正预期用途。我写过代理twisted http://twistedmatrix.com/documents/8.2.0/api/twisted.web.proxy.html之前,但我不确定如何将其与我想做的事情联系起来。到目前为止,这就是我所处的位置......

import os
import urlparse

import requests

import tornado.ioloop
import tornado.web
from tornado import template

ROOT = os.path.dirname(os.path.abspath(__file__))
path = lambda *a: os.path.join(ROOT, *a)

loader = template.Loader(path(ROOT, 'templates'))


class ProxyHandler(tornado.web.RequestHandler):
    def get(self, slug):
        if slug.startswith("http://") or slug.startswith("https://"):
            if self.get_argument("start", None) == "true":
                parsed = urlparse.urlparse(slug)
                self.set_cookie("scheme", value=parsed.scheme)
                self.set_cookie("netloc", value=parsed.netloc)
                self.set_cookie("urlpath", value=parsed.path)
            #external resource
            else:
                response = requests.get(slug)
                headers = response.headers
                if 'content-type' in headers:
                    self.set_header('Content-type', headers['content-type'])
                if 'length' in headers:
                    self.set_header('length', headers['length'])
                for block in response.iter_content(1024):
                    self.write(block)
                self.finish()
                return
        else:
            #absolute
            if slug.startswith('/'):
                slug = "{scheme}://{netloc}{original_slug}".format(
                    scheme=self.get_cookie('scheme'),
                    netloc=self.get_cookie('netloc'),
                    original_slug=slug,
                )
            #relative
            else:
                slug = "{scheme}://{netloc}{path}{original_slug}".format(
                    scheme=self.get_cookie('scheme'),
                    netloc=self.get_cookie('netloc'),
                    path=self.get_cookie('urlpath'),
                    original_slug=slug,
                )
        response = requests.get(slug)
        #get the headers
        headers = response.headers
        #get doctype
        doctype = None
        if '<!doctype' in response.content.lower()[:9]:
            doctype = response.content[:response.content.find('>')+1]
        if 'content-type' in headers:
           self.set_header('Content-type', headers['content-type'])
        if 'length' in headers:
            self.set_header('length', headers['length'])
        self.write(response.content)


application = tornado.web.Application([
    (r"/(.+)", ProxyHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

请注意,如果查询字符串中有 start=true,我设置一个 cookie 来保留方案、netloc 和 urlpath。这样,任何访问代理的相对或绝对链接都会使用该 cookie 来解析完整的 URL。

使用此代码,如果您转到http://localhost:8888/http://espn.com/?start=true你会看到 ESPN 的内容。但是,在以下网站上它根本不起作用:http://www.bottegaveneta.com/us/shop/ http://www.bottegaveneta.com/us/shop/。我的问题是,最好的方法是什么?我目前的实现方式是否可靠,或者是否存在一些可怕的陷阱?如果这是正确的,为什么像我指出的那样某些网站根本无法运行?

感谢您的任何帮助。


我最近写了一个类似的网络应用程序。请注意,这就是我的做法。我并不是说你应该这样做。以下是我遇到的一些陷阱:

将属性值从相对值更改为绝对值

涉及的不仅仅是获取页面并将其呈现给客户端。很多时候,您无法在没有任何错误的情况下代理网页。

为什么像我指出的那样某些网站根本无法运行?

许多网页依赖于资源的相对路径,以便以格式良好的方式显示网页。例如,这个图像标签:

<img src="/header.png" />

将导致客户端发出请求:

http://proxyurl/header.png

这失败了。这 'src' 值应转换为:

http://anothersite.com/header.png.

所以,你需要用类似的东西来解析 HTML 文档美丽汤 http://www.crummy.com/software/BeautifulSoup/, 循环所有标签并检查属性,例如:

'src', 'lowsrc', 'href'

And 改变他们的价值观相应地,标签变为:

<img src="http://anothersite.com/header.png" />

此方法不仅适用于图像标签,还适用于更多标签。a, script, link, li and frame有一些你也应该改变。

HTML 恶作剧

前面的方法应该能让你走得很远,但你还没有完成。

Both

<style type="text/css" media="all">@import "/stylesheet.css?version=120215094129002";</style>

And

<div style="position:absolute;right:8px;background-image:url('/Portals/_default/Skins/BE/images/top_img.gif');height:200px;width:427px;background-repeat:no-repeat;background-position:right top;" >

是难以访问和修改的代码示例美丽汤 http://www.crummy.com/software/BeautifulSoup/.

在第一个示例中,有一个 css @Import 到相对 uri。第二个涉及‘url()' 内联 CSS 语句中的方法。

在我的情况下,我最终编写了可怕的代码来手动修改这些值。您可能想为此使用正则表达式,但我不确定。

重定向

使用 Python-Requests 或 Urllib2,您可以轻松地自动跟踪重定向。只需记住保存新的(基本)uri 是什么;您将需要它来执行“将属性值从相对值更改为绝对值”操作。

您还需要处理“硬编码”重定向。比如这个:

<meta http-equiv="refresh" content="0;url=http://new-website.com/">

需要改为:

<meta http-equiv="refresh" content="0;url=http://proxyurl/http://new-website.com/">

Base tag

The base tag http://www.w3schools.com/tags/tag_base.asp指定文档中所有相对 URL 的基本 URL/目标。您可能想更改该值。

终于完成了?

没有。一些网站严重依赖 JavaScript 在屏幕上绘制内容。这些网站是最难代理的。我一直在考虑使用类似的东西PhantomJS http://phantomjs.org/ or Ghost http://jeanphix.me/Ghost.py/获取并评估网页并将结果呈现给客户端。

也许我的源代码 https://github.com/nattewasbeer/dushi.py-web/blob/master/bin/webdushi.py#L26可以帮你。您可以按照您想要的任何方式使用它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何用 Python 编写 Web 代理 的相关文章

  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • matplotlib 中的 R 风格数据轴缓冲区

    R 绘图自动设置 x 和 y 限制 以在数据和轴之间留出一些空间 我想知道 matplotlib 是否有办法自动执行相同的操作 如果没有 是否有一个好的公式或 经验法则 来说明 R 如何设置其轴限制 在 matplotlib 中 您可以通过
  • 组和平均 NumPy 矩阵

    假设我有一个任意的 numpy 矩阵 如下所示 arr 6 0 12 0 1 0 7 0 9 0 1 0 8 0 7 0 1 0 4 0 3 0 2 0 6 0 1 0 2 0 2 0 5 0 2 0 9 0 4 0 3 0 2 0 1 0
  • 类型错误:float() 参数必须是字符串或数字,而不是“列表”python

    我的 Python 有问题 这是我的代码 def calcola a input b float a 0 split c float a 0 split d float a 0 split e float a 0 split j float
  • Paramiko SSHException 通道已关闭

    我一直在使用 Paramiko 在 Linux Windows 机器上发送命令 它可以很好地在 Ubuntu 机器上远程执行测试 但是 它不适用于 Windows 7 主机 以下是我收到的错误 def unit for event self
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • 张量流和线程

    下面是来自 Tensorflow 网站的简单 mnist 教程 即单层 softmax 我尝试通过多线程训练步骤对其进行扩展 from tensorflow examples tutorials mnist import input dat
  • Python——捕获异常的效率[重复]

    这个问题在这里已经有答案了 可能的重复 Python 常见问题解答 异常有多快 https stackoverflow com questions 8107695 python faq how fast are exceptions 我记得
  • pandas 中连续数据的平行坐标图

    pandas 的 parallel coordinates 函数非常有用 import pandas import matplotlib pyplot as plt from pandas tools plotting import par
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 根据第三个变量更改散点图中的标记样式

    我正在处理多列字典 我想绘制两列 然后根据第三列和第四列更改标记的颜色和样式 我很难改变 pylab 散点图中的标记样式 我的方法适用于颜色 不幸的是不适用于标记样式 x 1 2 3 4 5 6 y 1 3 4 5 6 7 m k l l
  • Jupyter Notebook 中的深色模式绘图 - Python

    我正在使用 Jupyter Notebook 目前正在使用 JupyterThemes 的深色日光主题 我注意到我的绘图不是处于黑暗模式 并且文本仍然是黑色并且在日光照射的背景上无法读取 JupyterThemes 的自述文件建议在 ipy
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • Python 导入非常慢 - Anaconda python 2.7

    我的 python import 语句变得非常慢 我使用 Anaconda 包在本地运行 python 2 7 导入模块后 我编写的代码运行得非常快 似乎只是导入需要很长时间 例如 我使用以下代码运行了一个 tester py 文件 imp
  • 沿轴 0 重复 scipy csr 稀疏矩阵

    我想重复 scipy csr 稀疏矩阵的行 但是当我尝试调用 numpy 的重复方法时 它只是将稀疏矩阵视为对象 并且只会将其作为 ndarray 中的对象重复 我浏览了文档 但找不到任何实用程序来重复 scipy csr 稀疏矩阵的行 我
  • 如何在Tensorflow中保存估计器以供以后使用?

    我按照教程 TF Layers 指南 构建卷积神经网络 以下是代码 https github com tensorflow tensorflow blob r1 1 tensorflow examples tutorials layers
  • 如何从 nltk 下载器中删除数据/模型?

    我在 python3 NLTK 中安装了一些 NLTK 包 通过nltk download 尝试过它们 但不需要它们 现在想删除它们 我怎样才能删除例如包large grammars来自我的 NLTK 安装 我不想删除完整的 NLTK 安装
  • 在父类中访问子类变量

    我有一个父类和一个继承的子类 我想知道如何访问我的父类中的子类变量 我尝试了这个但失败了 class Parent object def init self print x class Child Parent x 1 x Child Er
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • C# gRPC 客户端拦截器设置授权标头

    我正在尝试为 gRPC 客户端创建一个拦截器 始终设置配置的 API 令牌 问题是我找不到设置的方法context Options Headers 如果我正在阅读文档 我需要致电WithHeaders方法 需要设置新的元数据 以便我可以添加
  • MySQL查询-比较版本号

    我的 SQL 表中有一个字段存储版本号 例如 3 4 23 or 1 224 43 有没有办法使用比 更棒该字段的条件 SELECT FROM versions WHERE version number gt 2 1 27 感谢 symcb
  • 访问类方法内的变量

    我正在使用 Tkinter Python 创建一个预算程序 这是我的代码的基础知识 class Expense def init self def Save self TotalAmount blah 所以我需要访问TotalAmount在
  • Maven 隐式“提供”依赖项未显示在“依赖项:树”中

    一位同事正在尝试建立一个新的 Spring 项目 该项目明确依赖于 spring security 而 spring security 又 隐式 依赖于 wss4j 在运行测试时 他遇到了缺少类的问题 我们已将缺失的类跟踪到 axis sa
  • 我应该使用 ASP:Label 标记吗?

    我正在 ASP NET 中构建一个表单来发送电子邮件 到目前为止 一切进展顺利 我能够将 ASP TextBox 内容传递到电子邮件 没有任何问题 现在 我的做法是将静态文本作为 TB 标签放入 然后使用 TB 控件作为输入 我应该使用 A
  • 无法锁定 DLL 上的 c++ 11 std::mutex [重复]

    这个问题在这里已经有答案了 我试图通过使用 std lock 对象来防止多次调用 DLL 初始化函数 在独立程序上使用这样的程序时 include
  • 对数据集的一部分进行多项式拟合的算法

    我有一个算法问题 我不知道 stackoverflow 是否是发布它的正确位置 但由于我使用 matlab 并且想用它来完成此操作 所以我将其发布在那里 我的问题如下 我有一组数据 除了在这组数据的末尾 这些点必须非常线性之外 我对此了解不
  • 使用 aiohttp 嵌套“异步”

    我想创建一个使用 aiohttp 进行 API 调用的调度程序类 我试过这个 import asyncio import aiohttp class MySession def init self self session None asy
  • TextInputEditText:ArgumentNullException:MvxWeakEventSubscription 中缺少源事件信息

    突然 我的 TextInputEditText 的绑定开始失败 这与链接器有关 如果我将链接器设置为 无 则一切都会按预期进行 我使用的许多其他绑定仍然可以正常工作 我得到的堆栈 视图绑定期间抛出异常 ArgumentNullExcepti
  • 在背景中捕捉图像?

    我试图在不加载相机或预览界面的情况下从相机捕获背景图像 在我的应用程序中 照片是在后台拍摄的 没有预览屏幕 只有普通的应用程序屏幕 然后稍后显示给用户 有人可以指出我正确的方向吗 您必须使用 AVCaptureSession 和 AVCap
  • 访问 RadioButton 并在 Espresso 中选择它

    我正在使用 Espresso 来测试 Android 应用程序 我在尝试找到一种方法来访问和选择当前活动的RadioButton 属于RadioGroup 时遇到麻烦 有没有人有什么建议 给出以下布局
  • 如何处理 mod_rewrite 中查询字符串中的“#”?

    I asked 这个问题 https stackoverflow com questions 1640977 how to redirect old ugly urls to seo friendly ones关于将旧的 丑陋 链接重写为搜
  • Java Servlet/Jsp 图像上传以及表单值[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个 jsp 表单 它接受有关员
  • 全局变量没有全局作用域

    supposedlyGlobalVariable blah ARoutine localVariable asdf MsgBox The global variable value is supposedlyGlobalVariable T
  • 访问 Bamboo 秘密/密码变量?

    我的团队有一些旧的竹子管道 其中秘密和密码在竹子变量中配置 并用竹子掩盖这些值 现在没有人知道密码 也没有记录下来 有什么方法可以访问 打印并查看bamboo 秘密 密码 变量中的值吗 读取秘密变量有一个技巧 创建包含内容的脚本任务 ech
  • 按条件对行进行分组

    我有这个数据 Start End Quantity 425 449 24 450 474 24 475 499 24 500 524 24 2300 2324 24 2400 2499 99 2500 2599 99 2800 2899 9
  • Mongoose:将 addToSet 与 ObjectIds 一起使用会产生孤立 ID

    我在使用 mongoDB addToSet 到一个充满对象 Id 的数组时遇到了一个相当有趣的问题 在我的猫鼬模式 Happening 中 我声明了一个名为 expected 的 ObjecId 数组 供 populate 使用 expec
  • 在 .Net Core 3.1 中使用 NewtonSoft 将 DataTable 转换为 JSON 字符串时,如何获得不带“\u0022”或“\”等字符的 JSON 字符串[重复]

    这个问题在这里已经有答案了 我正在 net core 3 1 中编写一个简单的 API 要将我的 DataTable 转换为 JSON 字符串 我使用 NewtonSoft 库和以下代码 string JSONresult JsonConv
  • 保护 JavaScript Web 应用程序/游戏的方法有哪些?

    背景故事 我计划实现一款休闲游戏 部署在网络应用程序中 但我不想使用 Flash 而只是使用普通的 Javascript 我想要的 Flash 的一个好处是 它分发二进制文件而不是源代码 因此更容易保护您的代码不被其他人重用 窃取 或者防止
  • 如何用 Python 编写 Web 代理

    我正在尝试用 python 编写一个网络代理 目标是访问如下网址 http proxyurl http anothersite com 并查看内容http anothersite com就像平常一样 通过滥用 requests 库 我已经取