16

编辑我现在意识到 API 根本不够用,甚至无法正常工作。我想重定向我的问题,我希望能够使用他们的“我感觉很笨”来自动搜索duckduckgo。这样我就可以搜索“stackoverflow”并获得主页(“ https://stackoverflow.com/ ”)作为我的结果。

我正在使用duckduckgo API。这里

我发现使用时:

r = duckduckgo.query("example")

结果不反映手动搜索,即:

for result in r.results:
    print result

结果是:

>>> 
>>> 

没有。

并且查找索引会results导致越界错误,因为它是空的。

我应该如何获得搜索结果?

似乎 API(根据其记录的示例)应该回答问题并以以下形式给出一种“我感觉很糟糕”r.answer.text

但是该网站的制作方式使我无法使用常规方法对其进行搜索和解析结果。

我想知道我应该如何使用这个 API 或来自这个站点的任何其他方法来解析搜索结果。

谢谢你。

4

5 回答 5

30

如果你访问DuckDuck Go API Page,你会发现一些关于使用 API 的注意事项。第一个注释清楚地表明:

由于这是一个零点击信息 API,大多数深度查询(非主题名称)将为空白。

这是这些字段的列表:

Abstract: ""
AbstractText: ""
AbstractSource: ""
AbstractURL: ""
Image: ""
Heading: ""
Answer: ""
Redirect: ""
AnswerType: ""
Definition: ""
DefinitionSource: ""
DefinitionURL: ""
RelatedTopics: [ ]
Results: [ ]
Type: ""

所以可能有点遗憾,但他们的 API 只是截断了一堆结果,并没有给你;可能工作得更快,除了使用DuckDuckGo.com之外似乎无能为力。

所以,显然,在这种情况下 API 不是要走的路。

至于我,我只看到了一条出路:从duckduckgo.com检索原始html并使用例如html5lib对其进行解析(值得一提的是,他们的html 结构良好)。

还值得一提的是,解析 html 页面并不是最可靠的数据报废方式,因为 html 结构可以更改,而 API 通常保持稳定,直到公开宣布更改。

下面是如何使用BeautifulSoup实现这种解析的示例:

from BeautifulSoup import BeautifulSoup
import urllib
import re

site = urllib.urlopen('http://duckduckgo.com/?q=example')
data = site.read()

parsed = BeautifulSoup(data)
topics = parsed.findAll('div', {'id': 'zero_click_topics'})[0]
results = topics.findAll('div', {'class': re.compile('results_*')})

print results[0].text

此脚本打印:

u'Eixample, an inner suburb of Barcelona with distinctive architecture'

在主页上直接查询的问题是它使用JavaScript产生所需的结果(不是相关主题),因此您只能使用HTML版本来获取结果。HTML 版本有不同的链接:

让我们看看我们能得到什么:

site = urllib.urlopen('http://duckduckgo.com/html/?q=example')
data = site.read()
parsed = BeautifulSoup(data)

first_link = parsed.findAll('div', {'class': re.compile('links_main*')})[0].a['href']

存储在first_link变量中的结果是指向搜索引擎输出的第一个结果(不是相关搜索)的链接:

http://www.iana.org/domains/example

要获取所有链接,您可以遍历找到的标签(可以以类似方式接收除链接之外的其他数据)

for i in parsed.findAll('div', {'class': re.compile('links_main*')}):
    print i.a['href']

http://www.iana.org/domains/example
https://twitter.com/example
https://www.facebook.com/leadingbyexample
http://www.trythisforexample.com/
http://www.myspace.com/leadingbyexample?_escaped_fragment_=
https://www.youtube.com/watch?v=CLXt3yh2g0s
https://en.wikipedia.org/wiki/Example_(musician)
http://www.merriam-webster.com/dictionary/example
...

请注意,仅 HTML 版本仅包含results,并且对于相关搜索,您必须使用 JavaScript 版本。(html网址中没有部分)。

于 2012-08-12T16:27:57.627 回答
2

在已经得到我接受并给予赏金的问题的答案之后 - 我找到了一个不同的解决方案,为了完整起见,我想在这里添加它。非常感谢所有帮助我找到这个解决方案的人。尽管这不是我要求的解决方案,但它可能会在未来帮助某人。

在本网站上进行了长时间的艰苦对话并附有一些支持邮件后发现:https ://duck.co/topic/strange-problem-when-searching-intel-with-my-script

这是解决方案代码(来自上面发布的线程中的答案):

>>> import duckduckgo
>>> print duckduckgo.query('! Example').redirect.url
http://www.iana.org/domains/example
于 2012-08-19T13:54:08.400 回答
0

尝试:

for result in r.results:
    print result.text
于 2012-07-30T14:35:33.020 回答
0

如果它适合您的应用程序,您也可以尝试相关搜索

r = duckduckgo.query("example")
for i in r.related_searches:
    if i.text:
        print i.text

这产生:

Eixample, an inner suburb of Barcelona with distinctive architecture
Example (musician), a British musician
example.com, example.net, example.org, example.edu  and .example, domain names reserved for use in documentation as examples
HMS Example (P165), an Archer-class patrol and training vessel of the British Royal Navy
The Example, a 1634 play by James Shirley
The Example (comics), a 2009 graphic novel by Tom Taylor and Colin Wilson
于 2012-08-12T18:07:51.790 回答
0

对于 python 3 用户,@Rostyslav Dzinko 代码的转录:

import re, urllib
import pandas as pd
from bs4 import BeautifulSoup

query = "your query"
site = urllib.request.urlopen("http://duckduckgo.com/html/?q="+query)
data = site.read()
soup = BeautifulSoup(data, "html.parser")

my_list = soup.find("div", {"id": "links"}).find_all("div", {'class': re.compile('.*web-result*.')})[0:15]


(result__snippet, result_url) = ([] for i in range(2))

for i in my_list:         
      try:
            result__snippet.append(i.find("a", {"class": "result__snippet"}).get_text().strip("\n").strip())
      except:
            result__snippet.append(None)
      try:
            result_url.append(i.find("a", {"class": "result__url"}).get_text().strip("\n").strip())
      except:
            result_url.append(None)
于 2017-08-16T14:39:15.400 回答