extract-webpage 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/index.d.ts +23 -0
- package/dist/config/serverRegistry.d.ts +7 -0
- package/dist/config/types.d.ts +4 -0
- package/dist/extract-webpage.cjs.js +2 -0
- package/dist/extract-webpage.cjs.js.map +1 -0
- package/dist/extract-webpage.es.js +5 -0
- package/dist/extract-webpage.es.js.map +1 -0
- package/dist/html-to-cite/extract-author.d.ts +11 -0
- package/dist/html-to-cite/extract-cite.d.ts +33 -0
- package/dist/html-to-cite/extract-date/date-extractors.d.ts +40 -0
- package/dist/html-to-cite/extract-date/date-validators.d.ts +15 -0
- package/dist/html-to-cite/extract-date/extract-date-quick.d.ts +8 -0
- package/dist/html-to-cite/extract-date/extract-date.d.ts +26 -0
- package/dist/html-to-cite/extract-source.d.ts +7 -0
- package/dist/html-to-cite/extract-title.d.ts +11 -0
- package/dist/html-to-cite/human-names-recognize.d.ts +16 -0
- package/dist/html-to-cite/metadata-to-cite.d.ts +12 -0
- package/dist/html-to-cite/url-to-domain.d.ts +20 -0
- package/dist/html-to-content/extract-content/extract-content-mercury-utils.d.ts +27 -0
- package/dist/html-to-content/extract-content/extract-content-mercury.d.ts +61 -0
- package/dist/html-to-content/extract-content/extract-content-readability.d.ts +101 -0
- package/dist/html-to-content/html-to-basic-html.d.ts +36 -0
- package/dist/html-to-content/html-to-content.d.ts +51 -0
- package/dist/html-to-content/html-utils.d.ts +76 -0
- package/dist/index.d.ts +26 -0
- package/dist/search/index.d.ts +14 -0
- package/dist/search/meta-search-agent-reexport.d.ts +8 -0
- package/dist/search/public-searxng.d.ts +47 -0
- package/dist/search/search-web.d.ts +33 -0
- package/dist/search/tavily.d.ts +20 -0
- package/dist/search/url-to-html.d.ts +62 -0
- package/dist/seektopic/fold-keyphrases.d.ts +28 -0
- package/dist/seektopic/ngrams.d.ts +27 -0
- package/dist/seektopic/rank-sentences-keyphrases.d.ts +28 -0
- package/dist/seektopic/seektopic-keyphrases.d.ts +53 -0
- package/dist/seektopic/types.d.ts +86 -0
- package/dist/seektopic/vector-search.d.ts +89 -0
- package/dist/seektopic/weight-keyphrases.d.ts +22 -0
- package/dist/suggest-next-words/autocomplete-ai.d.ts +0 -0
- package/dist/suggest-next-words/autocomplete-search-engines.d.ts +64 -0
- package/dist/tokenize/suggest-complete-word.d.ts +48 -0
- package/dist/tokenize/text-to-chunks.d.ts +48 -0
- package/dist/tokenize/text-to-sentences.d.ts +35 -0
- package/dist/tokenize/text-to-topic-tokens.d.ts +51 -0
- package/dist/tokenize/word-is-ignored.d.ts +12 -0
- package/dist/tokenize/word-to-root-stem.d.ts +16 -0
- package/dist/url-to-content/docx-to-content.d.ts +22 -0
- package/dist/url-to-content/is-url-adult.d.ts +26 -0
- package/dist/url-to-content/url-to-content.d.ts +127 -0
- package/dist/url-to-content/url-to-html.d.ts +60 -0
- package/dist/url-to-content/youtube-helpers.d.ts +23 -0
- package/dist/url-to-content/youtube-to-text.d.ts +70 -0
- package/dist/utils/documents.d.ts +4 -0
- package/dist/utils/grab.d.ts +18 -0
- package/package.json +109 -0
- package/src/config/env.ts +8 -0
- package/src/config/index.ts +233 -0
- package/src/config/serverRegistry.ts +24 -0
- package/src/config/types.ts +17 -0
- package/src/fs-mock.js +22 -0
- package/src/global.d.ts +8 -0
- package/src/html-to-cite/extract-author.ts +125 -0
- package/src/html-to-cite/extract-cite.ts +97 -0
- package/src/html-to-cite/extract-date/date-extractors.ts +484 -0
- package/src/html-to-cite/extract-date/date-validators.ts +191 -0
- package/src/html-to-cite/extract-date/extract-date-quick.ts +184 -0
- package/src/html-to-cite/extract-date/extract-date.ts +1049 -0
- package/src/html-to-cite/extract-source.ts +30 -0
- package/src/html-to-cite/extract-title.ts +78 -0
- package/src/html-to-cite/human-names-92k.json +1 -0
- package/src/html-to-cite/human-names-recognize.ts +396 -0
- package/src/html-to-cite/metadata-to-cite.ts +73 -0
- package/src/html-to-cite/url-to-domain.ts +50 -0
- package/src/html-to-content/extract-content/extract-content-mercury-utils.ts +696 -0
- package/src/html-to-content/extract-content/extract-content-mercury.ts +830 -0
- package/src/html-to-content/extract-content/extract-content-readability.ts +432 -0
- package/src/html-to-content/extract-content/extract-selectors-per-domain.json +3453 -0
- package/src/html-to-content/html-to-basic-html.ts +282 -0
- package/src/html-to-content/html-to-content.ts +97 -0
- package/src/html-to-content/html-utils.ts +398 -0
- package/src/index.ts +29 -0
- package/src/search/__tests__/public-searxng.test.ts +529 -0
- package/src/search/index.ts +43 -0
- package/src/search/meta-search-agent-reexport.ts +38 -0
- package/src/search/public-searxng.ts +470 -0
- package/src/search/search-web.ts +668 -0
- package/src/search/tavily.ts +106 -0
- package/src/search/url-to-html.ts +278 -0
- package/src/seektopic/fold-keyphrases.ts +87 -0
- package/src/seektopic/ngrams.ts +64 -0
- package/src/seektopic/rank-sentences-keyphrases.ts +132 -0
- package/src/seektopic/seektopic-keyphrases.ts +279 -0
- package/src/seektopic/types.ts +92 -0
- package/src/seektopic/vector-search.ts +232 -0
- package/src/seektopic/weight-keyphrases.ts +59 -0
- package/src/suggest-next-words/autocomplete-ai.ts +38 -0
- package/src/suggest-next-words/autocomplete-search-engines.ts +435 -0
- package/src/tokenize/suggest-complete-word.ts +137 -0
- package/src/tokenize/text-to-chunks.ts +150 -0
- package/src/tokenize/text-to-sentences.ts +614 -0
- package/src/tokenize/text-to-topic-tokens.ts +175 -0
- package/src/tokenize/word-is-ignored.ts +53 -0
- package/src/tokenize/word-to-root-stem.ts +151 -0
- package/src/types.d.ts +130 -0
- package/src/url-to-content/.fuse_hidden003bd28a0000000d +332 -0
- package/src/url-to-content/__tests__/url-to-content.test.ts +368 -0
- package/src/url-to-content/__tests__/url-to-html.test.ts +301 -0
- package/src/url-to-content/docx-to-content.ts +702 -0
- package/src/url-to-content/is-url-adult.ts +318 -0
- package/src/url-to-content/url-to-content.ts +367 -0
- package/src/url-to-content/url-to-html.ts +436 -0
- package/src/url-to-content/youtube-helpers.ts +64 -0
- package/src/url-to-content/youtube-to-text.ts +468 -0
- package/src/utils/documents.ts +71 -0
- package/src/utils/grab.ts +51 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview High-performance date extraction utility for HTML documents.
|
|
3
|
+
* Prioritizes meta tags, specific selectors, and URL patterns for fast results.
|
|
4
|
+
*/
|
|
5
|
+
// Constants
|
|
6
|
+
const DATE_PUBLISHED_META_TAGS = [
|
|
7
|
+
'article:published_time',
|
|
8
|
+
'displaydate',
|
|
9
|
+
'dc.date',
|
|
10
|
+
'dc.date.issued',
|
|
11
|
+
'rbpubdate',
|
|
12
|
+
'publish_date',
|
|
13
|
+
'pub_date',
|
|
14
|
+
'pagedate',
|
|
15
|
+
'pubdate',
|
|
16
|
+
'revision_date',
|
|
17
|
+
'doc_date',
|
|
18
|
+
'date_created',
|
|
19
|
+
'content_create_date',
|
|
20
|
+
'lastmodified',
|
|
21
|
+
'created',
|
|
22
|
+
'date',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const DATE_PUBLISHED_SELECTORS = [
|
|
26
|
+
'.hentry .dtstamp.published',
|
|
27
|
+
'.hentry .published',
|
|
28
|
+
'.hentry .dtstamp.updated',
|
|
29
|
+
'.hentry .updated',
|
|
30
|
+
'.single .published',
|
|
31
|
+
'.meta .published',
|
|
32
|
+
'.meta .postDate',
|
|
33
|
+
'.entry-date',
|
|
34
|
+
'.byline .date',
|
|
35
|
+
'.postmetadata .date',
|
|
36
|
+
'.article_datetime',
|
|
37
|
+
'.date-header',
|
|
38
|
+
'.story-date',
|
|
39
|
+
'.dateStamp',
|
|
40
|
+
'#story .datetime',
|
|
41
|
+
'.dateline',
|
|
42
|
+
'.pubdate',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const abbrevMonthsStr = '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)';
|
|
46
|
+
const DATE_PUBLISHED_URL_RES = [
|
|
47
|
+
new RegExp('/(20\\d{2}/\\d{2}/\\d{2})/', 'i'),
|
|
48
|
+
new RegExp('(20\\d{2}-[01]\\d-[0-3]\\d)', 'i'),
|
|
49
|
+
new RegExp(`/(20\\d{2}/${abbrevMonthsStr}/[0-3]\\d)/`, 'i'),
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const MS_DATE_STRING = /^\d{13}$/;
|
|
53
|
+
const SEC_DATE_STRING = /^\d{10}$/;
|
|
54
|
+
const CLEAN_DATE_STRING_RE = /^(.+?)(?: [a-z]{3})?(?::\d{2}| \d{4})? (?:[a-z]{3} )?[a-z]{3}$/i;
|
|
55
|
+
const TIME_AGO_STRING = /(\d+)\s+(.*?)\s+ago/;
|
|
56
|
+
const TIME_NOW_STRING = /^\s*(now|\d{1,2}\s*min(ute)?s?)\s*$/i;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extract date from document using various methods
|
|
60
|
+
*
|
|
61
|
+
* @param {Document} document - DOM object with article content
|
|
62
|
+
* @param {string} url - URL of the page
|
|
63
|
+
* @returns {string|null} Extracted date or null if not found
|
|
64
|
+
*/
|
|
65
|
+
export function extractDateQuick(document, url) {
|
|
66
|
+
let datePublished;
|
|
67
|
+
|
|
68
|
+
// Helper function to extract content from meta tags
|
|
69
|
+
function extractFromMeta(tags) {
|
|
70
|
+
for (const tag of tags) {
|
|
71
|
+
const metaTag = document.querySelector(`meta[name="${tag}"], meta[property="${tag}"]`);
|
|
72
|
+
if (metaTag) {
|
|
73
|
+
return metaTag.getAttribute('content');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Helper function to extract content from selectors
|
|
80
|
+
function extractFromSelectors(selectors) {
|
|
81
|
+
for (const selector of selectors) {
|
|
82
|
+
const element = document.querySelector(selector);
|
|
83
|
+
if (element) {
|
|
84
|
+
return element.textContent.trim();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 1. Check meta tags
|
|
91
|
+
datePublished = extractFromMeta(DATE_PUBLISHED_META_TAGS);
|
|
92
|
+
if (datePublished) return cleanDatePublished(datePublished);
|
|
93
|
+
|
|
94
|
+
// 2. Check selectors
|
|
95
|
+
datePublished = extractFromSelectors(DATE_PUBLISHED_SELECTORS);
|
|
96
|
+
if (datePublished) return cleanDatePublished(datePublished);
|
|
97
|
+
|
|
98
|
+
// 3. Check URL
|
|
99
|
+
for (const regex of DATE_PUBLISHED_URL_RES) {
|
|
100
|
+
const match = url.match(regex);
|
|
101
|
+
if (match) {
|
|
102
|
+
return cleanDatePublished(match[1]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 4. Check for specific text patterns
|
|
107
|
+
const textPatterns = ['Published', 'Updated', 'Posted'];
|
|
108
|
+
for (const pattern of textPatterns) {
|
|
109
|
+
for (const tag of ['time', 'span', 'div', 'p']) {
|
|
110
|
+
const elements = document.getElementsByTagName(tag);
|
|
111
|
+
for (const el of elements) {
|
|
112
|
+
if (el.textContent.includes(pattern)) {
|
|
113
|
+
datePublished = el.textContent.split(pattern)[1].trim();
|
|
114
|
+
if (datePublished) return cleanDatePublished(datePublished);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function cleanDatePublished(dateString) {
|
|
124
|
+
// If string is in milliseconds or seconds, convert to int and return
|
|
125
|
+
if (MS_DATE_STRING.test(dateString)) {
|
|
126
|
+
return new Date(parseInt(dateString, 10)).toISOString();
|
|
127
|
+
}
|
|
128
|
+
if (SEC_DATE_STRING.test(dateString)) {
|
|
129
|
+
return new Date(parseInt(dateString, 10) * 1000).toISOString();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
dateString = cleanDateString(dateString);
|
|
133
|
+
|
|
134
|
+
return dateString
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function cleanDateString(dateString) {
|
|
138
|
+
return dateString?.replace(CLEAN_DATE_STRING_RE, '$1').trim();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function createDate(dateString) {
|
|
142
|
+
if (TIME_AGO_STRING.test(dateString)) {
|
|
143
|
+
const [, amount, unit] = TIME_AGO_STRING.exec(dateString);
|
|
144
|
+
const now = new Date();
|
|
145
|
+
now.setMilliseconds(0);
|
|
146
|
+
switch (unit?.toLowerCase()) {
|
|
147
|
+
case 'second':
|
|
148
|
+
case 'seconds':
|
|
149
|
+
now.setSeconds(now.getSeconds() - parseInt(amount));
|
|
150
|
+
break;
|
|
151
|
+
case 'minute':
|
|
152
|
+
case 'minutes':
|
|
153
|
+
now.setMinutes(now.getMinutes() - parseInt(amount));
|
|
154
|
+
break;
|
|
155
|
+
case 'hour':
|
|
156
|
+
case 'hours':
|
|
157
|
+
now.setHours(now.getHours() - parseInt(amount));
|
|
158
|
+
break;
|
|
159
|
+
case 'day':
|
|
160
|
+
case 'days':
|
|
161
|
+
now.setDate(now.getDate() - parseInt(amount));
|
|
162
|
+
break;
|
|
163
|
+
case 'week':
|
|
164
|
+
case 'weeks':
|
|
165
|
+
now.setDate(now.getDate() - parseInt(amount) * 7);
|
|
166
|
+
break;
|
|
167
|
+
case 'month':
|
|
168
|
+
case 'months':
|
|
169
|
+
now.setMonth(now.getMonth() - parseInt(amount));
|
|
170
|
+
break;
|
|
171
|
+
case 'year':
|
|
172
|
+
case 'years':
|
|
173
|
+
now.setFullYear(now.getFullYear() - parseInt(amount));
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
return now;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (TIME_NOW_STRING.test(dateString)) {
|
|
180
|
+
return new Date();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return new Date(dateString);
|
|
184
|
+
}
|