././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1625081470.4619153
duckpy-3.2.0/ 0000755 0001750 0001750 00000000000 00000000000 012716 5 ustar 00alisson alisson ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1592641123.0
duckpy-3.2.0/LICENSE 0000644 0001750 0001750 00000002053 00000000000 013723 0 ustar 00alisson alisson MIT License
Copyright (c) 2020 Amano Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1625081470.4619153
duckpy-3.2.0/PKG-INFO 0000644 0001750 0001750 00000006606 00000000000 014023 0 ustar 00alisson alisson Metadata-Version: 2.1
Name: duckpy
Version: 3.2.0
Summary: A simple module for searching on DuckDuckGo
Home-page: https://github.com/AmanoTeam/duckpy
Author: Amano Team
Author-email: contact@amanoteam.com
License: MIT
Platform: UNKNOWN
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
A simple Python module for searching on DuckDuckGo.
 
## Installation
### Duckpy can be installed using pip with this command
```bash
pip install -U duckpy
```
### Alternatively, you can install the most recent version from git
```bash
pip install -U git+https://github.com/AmanoTeam/duckpy
```
### If you are using Debian or Ubuntu, you can install with this command (Currently only in Debian Unstable and Ubuntu 20.10+)
```bash
sudo apt install python3-duckpy
```
## Usage
```python
from duckpy import Client
client = Client()
results = client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
```
### We also provide an asynchronous version inside the `AsyncClient` class
```python
import asyncio
from duckpy import AsyncClient
client = AsyncClient()
async def get_results():
results = await client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
loop = asyncio.get_event_loop()
loop.run_until_complete(get_results())
```
### The result
```text
Python (programming language) - Wikipedia
https://en.wikipedia.org/wiki/Python_(programming_language)
Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991...
```
## Advanced usage
You can also set up proxies or set up custom User-Agent strings depending on your needs.
### Setting up proxies
DuckDuckGo may temporarily block your request IP or return empty results, especially if you are using the library for scraping, bots and other stuff that generate many requests. This is not a duckpy issue and can be prevented using proxies.
You can pass a list with proxies in the Client object, then duckpy will use these proxies to make requests:
```python
import duckpy
client = duckpy.Client(proxies=['http://123.45.67.89:80', 'https://98.76.54.32:443'])
```
If you pass more than one proxy, they will be randomly chosen every time you use the .search() method.
### Setting up custom User-Agents
```python
import duckpy
user_agents = [
"Mozilla/5.0 (X11; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
]
client = duckpy.Client(default_user_agents=user_agents)
```
Again, if you pass more than one User-Agent, they will be randomly chosen every time you use the .search() method.
## Disclaimer
We are not affiliated, associated, authorized, endorsed by, or in any way officially connected with DuckDuckGo, or any of its subsidiaries or its affiliates. The official DuckDuckGo website can be found at .
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1599715730.0
duckpy-3.2.0/README.md 0000644 0001750 0001750 00000006102 00000000000 014174 0 ustar 00alisson alisson
A simple Python module for searching on DuckDuckGo.
 
## Installation
### Duckpy can be installed using pip with this command
```bash
pip install -U duckpy
```
### Alternatively, you can install the most recent version from git
```bash
pip install -U git+https://github.com/AmanoTeam/duckpy
```
### If you are using Debian or Ubuntu, you can install with this command (Currently only in Debian Unstable and Ubuntu 20.10+)
```bash
sudo apt install python3-duckpy
```
## Usage
```python
from duckpy import Client
client = Client()
results = client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
```
### We also provide an asynchronous version inside the `AsyncClient` class
```python
import asyncio
from duckpy import AsyncClient
client = AsyncClient()
async def get_results():
results = await client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
loop = asyncio.get_event_loop()
loop.run_until_complete(get_results())
```
### The result
```text
Python (programming language) - Wikipedia
https://en.wikipedia.org/wiki/Python_(programming_language)
Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991...
```
## Advanced usage
You can also set up proxies or set up custom User-Agent strings depending on your needs.
### Setting up proxies
DuckDuckGo may temporarily block your request IP or return empty results, especially if you are using the library for scraping, bots and other stuff that generate many requests. This is not a duckpy issue and can be prevented using proxies.
You can pass a list with proxies in the Client object, then duckpy will use these proxies to make requests:
```python
import duckpy
client = duckpy.Client(proxies=['http://123.45.67.89:80', 'https://98.76.54.32:443'])
```
If you pass more than one proxy, they will be randomly chosen every time you use the .search() method.
### Setting up custom User-Agents
```python
import duckpy
user_agents = [
"Mozilla/5.0 (X11; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
]
client = duckpy.Client(default_user_agents=user_agents)
```
Again, if you pass more than one User-Agent, they will be randomly chosen every time you use the .search() method.
## Disclaimer
We are not affiliated, associated, authorized, endorsed by, or in any way officially connected with DuckDuckGo, or any of its subsidiaries or its affiliates. The official DuckDuckGo website can be found at .
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1625081470.4319148
duckpy-3.2.0/duckpy/ 0000755 0001750 0001750 00000000000 00000000000 014215 5 ustar 00alisson alisson ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1599715311.0
duckpy-3.2.0/duckpy/__init__.py 0000644 0001750 0001750 00000006704 00000000000 016335 0 ustar 00alisson alisson import asyncio
import random
import httpx
from .types import ResultDict
from typing import List
from warnings import warn
from typing import Union
from bs4 import BeautifulSoup
ddg_url = 'https://html.duckduckgo.com/html'
class BaseClient:
def __init__(self, proxies: Union[list, str] = None, default_user_agents: Union[list, str] = None, random_ua: bool = None):
if random_ua is not None:
warn("The random_ua parameter has been deprecated in favor of the default_user_agents parameter and will be removed in a future release.", DeprecationWarning, 2)
self.proxies = proxies
self.default_user_agents = default_user_agents
class Client(BaseClient):
def search(self, query: str, exact_match: bool = False, **kwargs) -> List[ResultDict]:
if exact_match:
query = '"%s"' % query
if isinstance(self.proxies, str):
proxy = self.proxies
elif isinstance(self.proxies, list):
proxy = random.choice(self.proxies) if self.proxies else None
else:
proxy = None
if isinstance(self.default_user_agents, str):
ua = self.default_user_agents
elif isinstance(self.default_user_agents, list):
ua = random.choice(self.default_user_agents) if self.default_user_agents else None
else:
ua = None
headers = {'User-Agent': ua} if ua else None
with httpx.Client(proxies=proxy, http2=True) as http:
r = http.post(ddg_url, data=dict(q=query, **kwargs), headers=headers)
data = r.read()
return parse_page(data)
class AsyncClient(BaseClient):
def __init__(self, proxies: Union[list, str] = None, default_user_agents: Union[list, str] = None, random_ua: bool = None):
self.loop = asyncio.get_event_loop()
super().__init__(proxies=proxies, default_user_agents=default_user_agents, random_ua=random_ua)
async def search(self, query: str, exact_match: bool = False, **kwargs) -> List[ResultDict]:
if exact_match:
query = '"%s"' % query
if isinstance(self.proxies, str):
proxy = self.proxies
elif isinstance(self.proxies, list):
proxy = random.choice(self.proxies) if self.proxies else None
else:
proxy = None
if isinstance(self.default_user_agents, str):
ua = self.default_user_agents
elif isinstance(self.default_user_agents, list):
ua = random.choice(self.default_user_agents) if self.default_user_agents else None
else:
ua = None
headers = {'User-Agent': ua} if ua else None
async with httpx.AsyncClient(proxies=proxy, http2=True) as http:
r = await http.post(ddg_url, data=dict(q=query, **kwargs), headers=headers)
data = r.read()
return await self.loop.run_in_executor(None, parse_page, data)
def parse_page(html: Union[str, bytes]) -> List[ResultDict]:
soup = BeautifulSoup(html, "html.parser")
results = []
for i in soup.find_all('div', {'class': 'links_main'}):
if i.find('a', {'class': 'badge--ad'}):
continue
try:
title = i.h2.a.text
description = i.find('a', {'class': 'result__snippet'}).text
url = i.find('a', {'class': 'result__url'}).get('href')
results.append(ResultDict(title=title, description=description, url=url))
except AttributeError:
pass
return results
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1625081470.451915
duckpy-3.2.0/duckpy/aio/ 0000755 0001750 0001750 00000000000 00000000000 014765 5 ustar 00alisson alisson ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1597819479.0
duckpy-3.2.0/duckpy/aio/__init__.py 0000644 0001750 0001750 00000000424 00000000000 017076 0 ustar 00alisson alisson # Just used for backwards compatibility.
from warnings import warn
from .. import AsyncClient as Client
warn("The duckpy.aio module has been deprecated in version 3.0.0 and will be removed in a future release. Please use duckpy.AsyncClient instead.", DeprecationWarning, 2)
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1599716084.0
duckpy-3.2.0/duckpy/types.py 0000644 0001750 0001750 00000000371 00000000000 015734 0 ustar 00alisson alisson class ResultDict(dict):
def __init__(self, title: str, description: str, url: str):
self.title = title
self.description = description
self.url = url
super().__init__(title=title, description=description, url=url)
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1625081470.451915
duckpy-3.2.0/duckpy.egg-info/ 0000755 0001750 0001750 00000000000 00000000000 015707 5 ustar 00alisson alisson ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081469.0
duckpy-3.2.0/duckpy.egg-info/PKG-INFO 0000644 0001750 0001750 00000006606 00000000000 017014 0 ustar 00alisson alisson Metadata-Version: 2.1
Name: duckpy
Version: 3.2.0
Summary: A simple module for searching on DuckDuckGo
Home-page: https://github.com/AmanoTeam/duckpy
Author: Amano Team
Author-email: contact@amanoteam.com
License: MIT
Platform: UNKNOWN
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
A simple Python module for searching on DuckDuckGo.
 
## Installation
### Duckpy can be installed using pip with this command
```bash
pip install -U duckpy
```
### Alternatively, you can install the most recent version from git
```bash
pip install -U git+https://github.com/AmanoTeam/duckpy
```
### If you are using Debian or Ubuntu, you can install with this command (Currently only in Debian Unstable and Ubuntu 20.10+)
```bash
sudo apt install python3-duckpy
```
## Usage
```python
from duckpy import Client
client = Client()
results = client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
```
### We also provide an asynchronous version inside the `AsyncClient` class
```python
import asyncio
from duckpy import AsyncClient
client = AsyncClient()
async def get_results():
results = await client.search("Python Wikipedia")
# Prints first result title
print(results[0].title)
# Prints first result URL
print(results[0].url)
# Prints first result description
print(results[0].description)
loop = asyncio.get_event_loop()
loop.run_until_complete(get_results())
```
### The result
```text
Python (programming language) - Wikipedia
https://en.wikipedia.org/wiki/Python_(programming_language)
Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991...
```
## Advanced usage
You can also set up proxies or set up custom User-Agent strings depending on your needs.
### Setting up proxies
DuckDuckGo may temporarily block your request IP or return empty results, especially if you are using the library for scraping, bots and other stuff that generate many requests. This is not a duckpy issue and can be prevented using proxies.
You can pass a list with proxies in the Client object, then duckpy will use these proxies to make requests:
```python
import duckpy
client = duckpy.Client(proxies=['http://123.45.67.89:80', 'https://98.76.54.32:443'])
```
If you pass more than one proxy, they will be randomly chosen every time you use the .search() method.
### Setting up custom User-Agents
```python
import duckpy
user_agents = [
"Mozilla/5.0 (X11; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
]
client = duckpy.Client(default_user_agents=user_agents)
```
Again, if you pass more than one User-Agent, they will be randomly chosen every time you use the .search() method.
## Disclaimer
We are not affiliated, associated, authorized, endorsed by, or in any way officially connected with DuckDuckGo, or any of its subsidiaries or its affiliates. The official DuckDuckGo website can be found at .
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081469.0
duckpy-3.2.0/duckpy.egg-info/SOURCES.txt 0000644 0001750 0001750 00000000351 00000000000 017572 0 ustar 00alisson alisson LICENSE
README.md
setup.py
duckpy/__init__.py
duckpy/types.py
duckpy.egg-info/PKG-INFO
duckpy.egg-info/SOURCES.txt
duckpy.egg-info/dependency_links.txt
duckpy.egg-info/requires.txt
duckpy.egg-info/top_level.txt
duckpy/aio/__init__.py ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081469.0
duckpy-3.2.0/duckpy.egg-info/dependency_links.txt 0000644 0001750 0001750 00000000001 00000000000 021755 0 ustar 00alisson alisson
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081469.0
duckpy-3.2.0/duckpy.egg-info/requires.txt 0000644 0001750 0001750 00000000057 00000000000 020311 0 ustar 00alisson alisson beautifulsoup4>=4.9.1
httpx[http2]<0.19,>=0.14
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081469.0
duckpy-3.2.0/duckpy.egg-info/top_level.txt 0000644 0001750 0001750 00000000007 00000000000 020436 0 ustar 00alisson alisson duckpy
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1625081470.4619153
duckpy-3.2.0/setup.cfg 0000644 0001750 0001750 00000000046 00000000000 014537 0 ustar 00alisson alisson [egg_info]
tag_build =
tag_date = 0
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1625081339.0
duckpy-3.2.0/setup.py 0000644 0001750 0001750 00000001053 00000000000 014427 0 ustar 00alisson alisson from setuptools import setup
with open('README.md') as f:
readme = f.read()
setup(
name='duckpy',
version='3.2.0',
packages=['duckpy', 'duckpy.aio'],
install_requires=['beautifulsoup4>=4.9.1', 'httpx[http2]>=0.14,<0.19'],
url='https://github.com/AmanoTeam/duckpy',
python_requires='>=3.6',
author='Amano Team',
author_email='contact@amanoteam.com',
license='MIT',
description='A simple module for searching on DuckDuckGo',
long_description=readme,
long_description_content_type='text/markdown'
)