Show HN: Headless Chrome Crawler
github.com
github.com
I haven’t looked into it, but I imagine it has a pretty clear fingerprint as well. So it would be easier to block than stock chrome in headless mode.
0 - https://github.com/GoogleChrome/puppeteer/issues/850 1 - https://github.com/cretz/chrome-screen-rec-poc/tree/master/a... 2 - https://bugs.chromium.org/p/chromium/issues/detail?id=706008
Let me quickly add instructions here, first you need to install some dependancies, add the following to dockerfile:
RUN apt-get install -y gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
Secondly, launch puppeteer with --no-sandbox option: browser = await puppeteer.launch({
args: ['--no-sandbox'] /*, headless: false*/
})
That should do it.[0]: https://github.com/yukinying/chrome-headless-browser-docker
Also using a real browser brings a lot of problems: high resource consumption, hangs, it is unclear when the page has finished loading etc. You have to supervise all browser processes. And if you use promises, there is high chance that you will miss error messages because promises hide them by default.
I'm grateful that "Obey robots.txt" is listed as part of it's standard behavior. If only scrapers cared enough to use it as well.
[1] https://www.digitalocean.com/community/tutorials/how-to-prot...
The stuff we are not seeing open-sourced is the solutions companies are building around trimmed down specialized versions of the headless browsers like Chrome headless, Servo, Webkit. People are running distributed versions of these headless browsers using Apache Mesos, Kubernetes, and Kafka queues.
Wget is also a pretty robust crawler, but people have requested a proxy that archives every site they visit in real-time more than a crawler.
Basically, when new page event happens, you get the `page` object where you have access to it and can do queries.
https://github.com/GoogleChrome/puppeteer/blob/v1.1.0/docs/a...
HCCrawler.launch({ // Function to be evaluated in browsers evaluatePage: (() => ({ title: $('title').text(), })), // Function to be called with evaluated results from browsers onSuccess: (result => { console.log(result); }), })
which doesn't look that good for my other worry, that you come to a dynamic JS built up page, load the DOM and evaluate in some milliseconds and then that DOM is changed after you've done your incorrect evaluation.
const page = await crawler.browser.newPage();
await page.goto(url);
await page.waitForSelector("a[href]");
const hrefs = await page.evaluate(
() => Array.from(document.body.querySelectorAll('a[href]'), ({ href }) => href)
);
and then you do something with hrefs.However if you have a page that loads with 4 links defined, does its script and then ends up 100+ links you miss the 100+ links. I notice people often failing to account for this in their crawlers, so I wondered if this one was.