allowed_domains 到底怎么匹配?子域名算不算?写错格式会怎样?被过滤的请求会通知谁?这篇既直接对着中间件做匹配表,也跑了真实抓取看 stats 与日志。
allowed_domains=['example.org'] ✓ ✓ ✓ ✓ ✓ ✗ ✗ ✗ ✓ ✗ ✗
allowed_domains=['www.example.org'] ✗ ✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
allowed_domains=['example.org', 'other.com'] ✓ ✓ ✓ ✓ ✓ ✗ ✗ ✗ ✓ ✗ ✗
allowed_domains=['example.org:8080'] ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
allowed_domains=['http://example.org'] ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗
allowed_domains=['127.0.0.1'] ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✗ ✓
allowed_domains=[] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
(下面编号对应的 URL) 1 2 3 4 5 6 7 8 9 0 1
1. http://example.org/a
2. http://www.example.org/a
3. http://bob.www.example.org/a
4. http://EXAMPLE.ORG/a
5. http://example.org:8080/a
6. http://notexample.org/a
7. http://example.org.evil.com/a
8. http://example.orgx/a
9. http://api.example.org/a
10. http://[::1]/a
11. http://127.0.0.1:9000/a主机名必须等于 allowed_domains 的某一项,或者是它的子域名;大小写不敏感(主机名先小写),端口和协议被忽略,所以带端口或协议的写法永远匹配不上。
回调被调用的页面:['/', 'on'];服务器收到 ['/', '/on'];offsite stats {'domains': 1, 'filtered': 4}
日志:[scrapy.downloadermiddlewares.offsite] DEBUG: Filtered offsite request to 'localhost': <GET http://localhost:9960/off1>OffsiteMiddleware 在请求进入调度器时就抛 IgnoreRequest,请求不会发出,也没有回调,stats 里记 offsite/filtered 和 offsite/domains。
meta allow_offsite = True 服务器收到 ['/', '/off2', '/on', '/off1'];offsite stats {}
dont_filter = True 服务器收到 ['/', '/off2', '/on', '/off1'];offsite stats {}
不设 allowed_domains 服务器收到 ['/', '/off2', '/on', '/off1'];offsite stats {}请求 meta 里 allow_offsite = True 或 dont_filter = True 就不受限制;不设 allowed_domains 则全部放行。
回调/errback 被调用的次数:0(被过滤的请求既没有回调也没有 errback,静默丢弃)
服务器收到 ['/to-local'];offsite stats {'domains': 1, 'filtered': 2}手写的起始请求和重定向产生的请求同样受限;默认的 start_urls 请求自带 dont_filter = True,不受限。
start_urls 指向站外 localhost:回调 ['via-start-urls'];服务器收到 ['/via-start-urls'];offsite stats {}起始 URL 想受 allowed_domains 约束,就在 start() 里自己 yield 不带 dont_filter 的 Request。