【问题标题】:MITMProxy: smart URL replacementMITMProxy:智能 URL 替换
【发布时间】:2014-07-22 11:37:35
【问题描述】:

我们使用自定义抓取工具,必须为一种语言获取单独的网站(这是架构限制)。如 site1.co.uk、site1.es、site1.de 等。

但是我们需要解析一个有多种语言的网站,用 url 分隔——比如 site2.com/en、site2.com/de、site2.com/es 等等。

我想到了 MITMProxy:我可以通过这种方式重定向所有请求:

en.site2.com/* --> site2.com/en
de.site2.com/* --> site2.com/de
...

我写了一个小脚本,它只需要 URL 并重写它们:

class MyMaster(flow.FlowMaster):

  def handle_request(self, r):
    url = r.get_url()

    # replace URLs
    if 'blabla' in url:
      r.set_url(url.replace('something', 'another'))

但目标主机生成 301 重定向,并带有来自网络服务器的响应 - “页面已移至此处”以及指向 site2.com/en 的链接

当我使用 URL 重写时它起作用了,即 site2.com/en --> site2.com/de。 但是对于不同的主机(准确地说是子域和根域),就不行了。

我尝试从上面替换 handle_request 方法中的 Host 标头:

for key in r.headers.keys():
        if key.lower() == 'host':
            r.headers[key] = ['site2.com']

我也尝试替换推荐人 - 所有这些都没有帮助。

我怎样才能最终将该请求从子域欺骗到主域?如果它生成一个 HTTP(s) 客户端警告,那没关系,因为我们需要它用于爬虫(并且可以关闭那里的警告),而不是真正的浏览器。

谢谢!

【问题讨论】:

    标签: python mitmproxy


    【解决方案1】:

    您需要替换响应的内容并仅使用几个字段来制作标题。 打开到重定向网址的新连接并制作您的响应:

    def handle_request(self, flow):
      newUrl = <new-url>
      retryCount = 3
      newResponse = None
      while True:
        try:
          newResponse = requests.get(newUrl) # import requests
        except: 
          if retryCount == 0:
            print 'Cannot reach new url ' + newUrl
            traceback.print_exc() # import traceback
            return
    
          retryCount -= 1
          continue
        break
    
      responseHeaders = Headers() # from netlib.http import Headers
    
      if 'Date' in newResponse.headers:
        responseHeaders['Date'] = str(newResponse.headers['Date'])
      if 'Connection' in newResponse.headers:
        responseHeaders['Connection'] = str(newResponse.headers['Connection'])
      if 'Content-Type' in newResponse.headers:
        responseHeaders['Content-Type'] = str(newResponse.headers['Content-Type'])
      if 'Content-Length' in newResponse.headers:
        responseHeaders['Content-Length'] = str(newResponse.headers['Content-Length'])
      if 'Content-Encoding' in newResponse.headers:
        responseHeaders['Content-Encoding'] = str(inetResponse.headers['Content-Encoding'])
    
      response = HTTPResponse(   # from libmproxy.models import HTTPResponse
        http_version='HTTP/1.1',
        status_code=200,
        reason='OK',
        headers=responseHeaders,
        content=newResponse.content)
    
      flow.reply(response)
    

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 2011-10-21
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 2015-02-18
      相关资源
      最近更新 更多