-
-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathgetArticleContent.js
More file actions
79 lines (64 loc) · 2.49 KB
/
Copy pathgetArticleContent.js
File metadata and controls
79 lines (64 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
const { Readability } = require('@mozilla/readability');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { cleanText } = require('./cleanText');
const verifyMessages = [
"you are human",
"are you human",
"i'm not a robot",
"recaptcha"
];
const getArticleContent = async ({ articles, browser, filterWords, logger }) => {
try {
const processedArticlesPromises = articles.map(article =>
extractArticleContentAndFavicon({article, browser, filterWords, logger})
);
const processedArticles = await Promise.all(processedArticlesPromises);
return processedArticles;
} catch (err) {
logger.error("getArticleContent ERROR:", err);
return articles;
}
}
const extractArticleContentAndFavicon = async ({
article, browser, filterWords, logger
}) => {
const page = await browser.newPage();
try {
await page.goto(article.link, { waitUntil: 'networkidle2' });
const content = await page.evaluate(() => document.documentElement.innerHTML);
const favicon = await page.evaluate(() => {
const link = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
return link ? link.getAttribute('href') : '';
}) || "";
const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.on("error", logger.error);
const dom = new JSDOM(content, { url: article.link, virtualConsole });
let reader = new Readability(dom.window.document);
const articleContent = reader.parse();
if (!articleContent || !articleContent.textContent) {
logger.warn("Article content could not be parsed or is empty.", {article});
return { ...article, content: '', favicon};
}
const hasVerifyMessage = verifyMessages.find(w => (articleContent.textContent || '').toLowerCase().includes(w));
if (hasVerifyMessage) {
logger.warn("Article requires human verification.", {article});
return { ...article, content: '', favicon};
}
const cleanedText = cleanText(articleContent.textContent, filterWords || []);
if (cleanedText.split(' ').length < 100) {
logger.warn("Article content is too short and likely not valuable.", {article});
return { ...article, content: '', favicon };
}
logger.info("SUCCESSFULLY SCRAPED ARTICLE CONTENT:", cleanedText);
return { ...article, content: cleanedText, favicon};
} catch (error) {
logger.error(error);
return { ...article, content: '', favicon: '' };
} finally {
await page.close();
}
}
module.exports = {
default: getArticleContent
}