Skip to content

Commit 5b4d53e

Browse files
authored
Add text_content kwarg to BrowserlessLoader (langchain-ai#7856)
Added keyword argument to toggle between getting the text content of a site versus its HTML when using the `BrowserlessLoader`
1 parent 2aa3cf4 commit 5b4d53e

2 files changed

Lines changed: 75 additions & 26 deletions

File tree

docs/extras/modules/data_connection/document_loaders/integrations/browserless.ipynb

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
"cell_type": "markdown",
66
"metadata": {},
77
"source": [
8-
"# Browserless"
8+
"# Browserless\n",
9+
"\n",
10+
"Browserless is a service that allows you to run headless Chrome instances in the cloud. It's a great way to run browser-based automation at scale without having to worry about managing your own infrastructure.\n",
11+
"\n",
12+
"To use Browserless as a document loader, initialize a `BrowserlessLoader` instance as shown in this notebook. Note that by default, `BrowserlessLoader` returns the `innerText` of the page's `body` element. To disable this and get the raw HTML, set `text_content` to `False`."
913
]
1014
},
1115
{
1216
"cell_type": "code",
13-
"execution_count": 1,
17+
"execution_count": 11,
1418
"metadata": {},
1519
"outputs": [],
1620
"source": [
@@ -19,26 +23,44 @@
1923
},
2024
{
2125
"cell_type": "code",
22-
"execution_count": null,
26+
"execution_count": 12,
2327
"metadata": {},
2428
"outputs": [],
2529
"source": [
26-
"BROWSERLESS_API_TOKEN = \"YOUR_API_TOKEN\""
30+
"BROWSERLESS_API_TOKEN = \"YOUR_BROWSERLESS_API_TOKEN\""
2731
]
2832
},
2933
{
3034
"cell_type": "code",
31-
"execution_count": 2,
35+
"execution_count": 14,
3236
"metadata": {},
3337
"outputs": [
3438
{
3539
"name": "stdout",
3640
"output_type": "stream",
3741
"text": [
38-
"<!DOCTYPE html><html class=\"client-js vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-enabled vector-feature-main-menu-pinned-disabled vector-feature-limited-width-enabled vector-feature-limited-width-content-enabled vector-feature-zebra-design-disabled\" lang=\"en\" dir=\"ltr\"><head>\n",
39-
"<meta charset=\"UTF-8\">\n",
40-
"<title>Document classification - Wikipedia</title>\n",
41-
"<script>document.documentElement.className=\"client-js vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-enabled vector-feature-main-menu-pinned-disabled vector-feature-limited-width-enabled vector-feature-limited-width-content-enabled vector-feature-zebra-design-disabled\";(function(){var cookie=document.cookie.match(/(?:^|; )enwikimwclien\n"
42+
"Jump to content\n",
43+
"Main menu\n",
44+
"Search\n",
45+
"Create account\n",
46+
"Log in\n",
47+
"Personal tools\n",
48+
"Toggle the table of contents\n",
49+
"Document classification\n",
50+
"17 languages\n",
51+
"Article\n",
52+
"Talk\n",
53+
"Read\n",
54+
"Edit\n",
55+
"View history\n",
56+
"Tools\n",
57+
"From Wikipedia, the free encyclopedia\n",
58+
"\n",
59+
"Document classification or document categorization is a problem in library science, information science and computer science. The task is to assign a document to one or more classes or categories. This may be done \"manually\" (or \"intellectually\") or algorithmically. The intellectual classification of documents has mostly been the province of library science, while the algorithmic classification of documents is mainly in information science and computer science. The problems are overlapping, however, and there is therefore interdisciplinary research on document classification.\n",
60+
"\n",
61+
"The documents to be classified may be texts, images, music, etc. Each kind of document possesses its special classification problems. When not otherwise specified, text classification is implied.\n",
62+
"\n",
63+
"Do\n"
4264
]
4365
}
4466
],
@@ -48,6 +70,7 @@
4870
" urls=[\n",
4971
" \"https://en.wikipedia.org/wiki/Document_classification\",\n",
5072
" ],\n",
73+
" text_content=True,\n",
5174
")\n",
5275
"\n",
5376
"documents = loader.load()\n",
@@ -72,7 +95,7 @@
7295
"name": "python",
7396
"nbconvert_exporter": "python",
7497
"pygments_lexer": "ipython3",
75-
"version": "3.11.1"
98+
"version": "3.10.9"
7699
},
77100
"orig_nbformat": 4
78101
},

langchain/document_loaders/browserless.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,58 @@
99
class BrowserlessLoader(BaseLoader):
1010
"""Loads the content of webpages using Browserless' /content endpoint"""
1111

12-
def __init__(self, api_token: str, urls: Union[str, List[str]]):
12+
def __init__(
13+
self, api_token: str, urls: Union[str, List[str]], text_content: bool = True
14+
):
1315
"""Initialize with API token and the URLs to scrape"""
1416
self.api_token = api_token
1517
"""Browserless API token."""
1618
self.urls = urls
1719
"""List of URLs to scrape."""
20+
self.text_content = text_content
1821

1922
def lazy_load(self) -> Iterator[Document]:
2023
"""Lazy load Documents from URLs."""
2124

2225
for url in self.urls:
23-
response = requests.post(
24-
"https://chrome.browserless.io/content",
25-
params={
26-
"token": self.api_token,
27-
},
28-
json={
29-
"url": url,
30-
},
31-
)
32-
yield Document(
33-
page_content=response.text,
34-
metadata={
35-
"source": url,
36-
},
37-
)
26+
if self.text_content:
27+
response = requests.post(
28+
"https://chrome.browserless.io/scrape",
29+
params={
30+
"token": self.api_token,
31+
},
32+
json={
33+
"url": url,
34+
"elements": [
35+
{
36+
"selector": "body",
37+
}
38+
],
39+
},
40+
)
41+
yield Document(
42+
page_content=response.json()["data"][0]["results"][0]["text"],
43+
metadata={
44+
"source": url,
45+
},
46+
)
47+
else:
48+
response = requests.post(
49+
"https://chrome.browserless.io/content",
50+
params={
51+
"token": self.api_token,
52+
},
53+
json={
54+
"url": url,
55+
},
56+
)
57+
58+
yield Document(
59+
page_content=response.text,
60+
metadata={
61+
"source": url,
62+
},
63+
)
3864

3965
def load(self) -> List[Document]:
4066
"""Load Documents from URLs."""

0 commit comments

Comments
 (0)