Eri*_*icM 6 ruby mechanize mechanize-ruby
我写了一个脚本,它将遍历我们数据库中的所有客户,验证他们的网站URL是否有效,并尝试在他们的主页上找到推特链接.我们有超过10,000个网址需要验证.如果验证了网址的一小部分,我们就开始为每个网址获取getaddrinfo错误.
以下是抓取单个网址的代码副本:
def scrape_url(url)
url_found = false
twitter_name = nil
begin
agent = Mechanize.new do |a|
a.follow_meta_refresh = true
end
agent.get(normalize_url(url)) do |page|
url_found = true
twitter_name = find_twitter_name(page)
end
@err << "[#{@current_record}] SUCCESS\n"
rescue Exception => e
@err << "[#{@current_record}] ERROR (#{url}): "
@err << e.message
@err << "\n"
end
[url_found, twitter_name]
end
Run Code Online (Sandbox Code Playgroud)
注意:我还运行了此代码的一个版本,该版本创建了一个在所有对scrape_url的调用中共享的Mechanize实例.它以完全相同的方式失败了.
当我在EC2上运行它时,它几乎完全通过1,000个URL,然后为剩余的9,000+返回此错误:
getaddrinfo: Temporary failure in name resolution
Run Code Online (Sandbox Code Playgroud)
请注意,我已经尝试使用亚马逊的DNS服务器和谷歌的DNS服务器,认为它可能是一个合法的DNS问题.在这两种情况下,我得到了完全相同的结果.
然后,我尝试在我当地的MacBook Pro上运行它.在为剩余的记录返回此错误之前,它只通过了大约250个:
getaddrinfo: nodename nor servname provided, or not known
Run Code Online (Sandbox Code Playgroud)
有谁知道如何让脚本通过所有记录?
Eri*_*icM 10
我找到了解决方案.Mechanize正在打开连接并依靠GC来清理它们.在某一点之后,有足够的开放连接,无法建立额外的出站连接来进行DNS查找.这是导致它工作的代码:
agent = Mechanize.new do |a|
a.follow_meta_refresh = true
a.keep_alive = false
end
Run Code Online (Sandbox Code Playgroud)
通过将keep_alive设置为false,立即关闭并清除连接.
| 归档时间: |
|
| 查看次数: |
1645 次 |
| 最近记录: |