在 Python 中抓取 - 防止 IP 禁令
Posted
技术标签:
【中文标题】在 Python 中抓取 - 防止 IP 禁令【英文标题】:Scraping in Python - Preventing IP ban 【发布时间】:2016-05-10 01:28:48 【问题描述】:我正在使用Python
来抓取页面。到目前为止,我没有遇到任何复杂的问题。
我试图抓取的网站使用了大量的安全检查,并有一些机制来防止抓取。
使用 Requests
和 lxml
在被 IP 禁止之前,我能够抓取大约 100-150 页。有时我什至会禁止第一次请求(新 IP,以前未使用过,不同的 C 块)。我试过欺骗头,随机化请求之间的时间,还是一样。
我已经尝试过使用 Selenium,我得到了更好的结果。使用 Selenium,我可以在被禁止之前刮掉大约 600-650 页。在这里,我还尝试随机化请求(在 3-5 秒之间,并在每 300 个请求上调用time.sleep(300)
)。尽管如此,我还是被禁止了。
从这里我可以得出结论,如果网站在一个打开的浏览器会话中请求超过 X 个页面或类似的东西,他们会禁止 IP。
根据您的经验,我还应该尝试什么? 将在 Selenium 帮助中关闭和打开浏览器(例如在每 100 个请求关闭和打开浏览器之后)。我正在考虑尝试使用代理,但大约有数百万页,而且会非常广泛。
【问题讨论】:
【参考方案1】:如果您切换到Scrapy
web-scraping framework,您将能够重复使用许多用于防止和解决禁令的东西:
旋转用户代理与这是一个基于 Scrapy 服务器和您正在抓取的网站的负载自动限制抓取速度的扩展。
scrapy-fake-useragent
中间件:
使用 fake-useragent 每个请求提供的随机用户代理
轮换 IP 地址:
Setting Scrapy proxy middleware to rotate on each requestscrapy-proxies
您也可以通过本地代理和 TOR 运行它:
Scrapy: Run Using TOR and Multiple Agents【讨论】:
我不是 Scrapy 的粉丝,但我可能会尝试一下,虽然我不确定它是否会帮助我。我已经使用了您推荐的所有东西,并且无法通过限制。 @RhymeGuy 这只是一个一般性的答案,以便它可以帮助其他访问该主题的人。在您的情况下,我会说通过代理切换 IP 是可行的方法。谢谢。【参考方案2】:我也有这个问题。我在python3
中使用了urllib
和tor
。
-
download 并安装 Tor 浏览器
测试器
打开终端并输入:
curl --socks5-hostname localhost:9050 <http://site-that-blocked-you.com>
如果你看到结果,它就起作用了。
-
现在我们应该在 python 中进行测试。现在运行这段代码
import socks
import socket
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
#set socks5 proxy to use tor
socks.set_default_proxy(socks.SOCKS5, "localhost", 9050)
socket.socket = socks.socksocket
req = Request('http://check.torproject.org', headers='User-Agent': 'Mozilla/5.0', )
html = urlopen(req).read()
soup = BeautifulSoup(html, 'html.parser')
print(soup('title')[0].get_text())
如果你看到
恭喜。此浏览器配置为使用 Tor。
它也在 python 中工作,这意味着你正在使用 tor 进行网络抓取。
【讨论】:
只是想更新一下,tor浏览器现在监听的是9150端口而不是9050。 无法连接到本地主机。 在所有这些操作之后我仍然被IP地址禁止【参考方案3】:你可以使用代理。
您可以以非常便宜的价格购买数百个 IP,并像以前一样使用 selenium。 此外,我建议更改您使用的浏览器和其他用户代理参数。
您可以使用单个 IP 地址进行迭代,以仅加载 x 个页面并在被禁止之前停止。
def load_proxy(PROXY_HOST,PROXY_PORT):
fp = webdriver.FirefoxProfile()
fp.set_preference("network.proxy.type", 1)
fp.set_preference("network.proxy.http",PROXY_HOST)
fp.set_preference("network.proxy.http_port",int(PROXY_PORT))
fp.set_preference("general.useragent.override","whater_useragent")
fp.update_preferences()
return webdriver.Firefox(firefox_profile=fp)
【讨论】:
你能推荐我可能使用的代理服务吗? 谢谢,服务看起来还不错,但并不便宜。我什至不确定我为代理支付的钱是否能涵盖我将收集的信息的价值。将不得不重新考虑。 如果你搜索的页面是被谷歌缓存的,你可以在谷歌中搜索并访问谷歌爬虫缓存的静态版本吗? 不幸的是,网站使用登录表单,大多数页面在没有登录的情况下无法访问。因此 Google 无法缓存它们。似乎在这种情况下使用代理服务是唯一合理的选择。 我们如何使用 chrome web-driver selenium 和 python 更改 IP以上是关于在 Python 中抓取 - 防止 IP 禁令的主要内容,如果未能解决你的问题,请参考以下文章