【问题标题】:Website blocking out curl even with real browser's headers即使使用真正的浏览器标题,网站也会屏蔽 curl
【发布时间】:2017-04-16 04:51:56
【问题描述】:

我注意到http://www.momondo.com.cn/ 正在使用一些神奇的技术: curl 不起作用。该 URL 在 Web 浏览器中显示良好,但 curl 总是返回超时,即使我像 Web 浏览器一样添加所有标头。

我也尝试过 Python 请求和urllib2,但它们也不起作用。

C:\Users\Administrator>curl -v -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36" -H "Connection: Keep-Alive" -H "Accept-Encoding:gzip, deflate, sdch" -H "Cache-Control:no-cache" -H "Upgrade-Insecure-Requests:1" -H "Accept-Language:zh-CN,zh;q=0.8" -H "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
http://www.momondo.com.cn/
* About to connect() to www.momondo.com.cn port 80 (#0)
*   Trying 184.50.91.106...
* connected
* Connected to www.momondo.com.cn (184.50.91.106) port 80 (#0)
> GET / HTTP/1.1
> Host: www.momondo.com.cn
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
> Connection: Keep-Alive
> Accept-Encoding:gzip, deflate, sdch
> Cache-Control:no-cache
> Upgrade-Insecure-Requests:1
> Accept-Language:zh-CN,zh;q=0.8
> Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
>

为什么以及如何发生这种情况? Momondo是如何逃出curl的?

【问题讨论】:

  • 这太宽泛了。有许多技术可以对非浏览器流量进行指纹识别;抓取内容的最佳方法是使用无头浏览器。
  • 是的,我知道,有些网站可以通过 Javascript 检测。但我很惊讶 momondo 可以通过与真正的浏览器相同的第一个任务进行检测。

标签: python curl web-scraping web-crawler


【解决方案1】:

您如何设置请求?如果您使用requests,您应该使用Session 对象类型并更改那里的标题,以便它们可以轻松重用。看起来他们没有做任何特别的事情,因为直接在该站点上使用 telnet(即telnet www.momondo.com.cn 80)和浏览器生成的标题(通过tcpdump 捕获,只是为了确定)导致返回内容而不是挂起直到超时。此外,它还注意查看该站点背后的 CDN(内容交付网络),在这种情况下,地址解析为 akamaiedge.net 的某个子域,这意味着查看 why they might have blocked you 可能很有用。

无论如何,使用您提供的带有 requests.Session 对象的标头,生成了响应。

>>> from requests import Session
>>> session = Session()
>>> session.headers  # check the default headers
{'User-Agent': 'python-requests/2.12.5', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*'}
>>> session.headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
>>> session.headers['Accept-Language'] = 'en-GB,en-US;q=0.8,en;q=0.6,zh-TW;q=0.4'
>>> session.headers['Cache-Control'] = 'max-age=0'
>>> session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36'
>>> response = session.get('http://www.momondo.com.cn/')
>>> response
<Response [200]>

似乎一点也不神奇。

【讨论】:

  • 谢谢。请求的会话使用 keep-alive 并使用默认编码。所以它起作用了。
【解决方案2】:

我知道原因了:

momondo 正在使用以下方法来阻止虚幻 Web 客户端。

  1. 检测用户代理。不能是 curl 的默认 UA。
  2. 检测“连接”标头。在我的初始测试中必须使用“keep-alive”而不是“Keep-Alive”。
  3. 检测“Accept-Encoding”标头。不能为空,可以使用任何东西。

我现在终于可以使用 curl 来获取内容了:

curl -v -H "用户代理: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, 像 Gecko) Chrome/44.0.2403.89 Safari/537.36" -H "连接:保持活动状态" -H "接受编码: 什么都没有”http://www.momondo.com.cn/

顺便说一句,我从事网络抓取工作大约七年了。这是我第一次遇到使用这种防刮方法的网站。标记一下。

【讨论】:

  • 请注意,Accept-Encoding 标头也可以替换为 Accept-Language 标头,例如-H "Accept-Language: zh-CN,zh;q=0.8"。很确定它会检查一些标头,如果最小数量检查请求是否通过。
  • 你是对的。而且我注意到它可能会使用浏览器版本跟踪 ip。例如'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:56.0) Gecko/20100101 Firefox/50.0' 工作,而 '... Firefox/17.0' 不工作。
  • 它也可能会记住您的浏览器。如果您首先使用“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36”,然后使用“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" 将不起作用。
猜你喜欢
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 1970-01-01
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 2018-02-23
相关资源
最近更新 更多