मैंने पाठ को खुरचने के लिए नोड में एक छोटा प्रोग्राम (जिसे अर्क.जेएस कहा जाता है) लिखकर इस समस्या को हल किया। मैंने इस पृष्ठ का उपयोग मेरी मदद करने के लिए किया: http://blog.miguelgrinberg.com/post/easy-web-scraping-with-nodejs
प्रत्येक HTML पृष्ठ में कई पुस्तक पृष्ठ होते हैं। इसलिए अगर हम url में पेज पैरामीटर को केवल 1 से बढ़ाते हैं तो हम डुप्लिकेट बुक पेज को स्क्रैप कर देंगे यदि हम सावधान नहीं हैं (यह वह हिस्सा था जिसे मैं विशेष रूप से अटका रहा था)। मैंने इसके लिए jquery चयनकर्ता का उपयोग करके केवल url में निर्दिष्ट व्यक्तिगत पुस्तक पृष्ठ का चयन किया और html में मौजूद अन्य पुस्तक पृष्ठों की उपेक्षा की। इस तरह मैं क्रम में प्रत्येक एकल पृष्ठ के लिए यूआरएल के साथ स्प्रेडशीट प्रोग्राम का उपयोग करके एक पाठ फ़ाइल का निर्माण कर सकता था (क्योंकि वेतन वृद्धि केवल 1 है)।
अब तक मैंने पहले दो संस्करणों को सफलतापूर्वक समाप्त कर दिया है, पांच और जाने के लिए! कोड नीचे दिया गया है, यह अन्य Google पुस्तकों को स्क्रैप करने के लिए एक उपयोगी स्टार्टर के रूप में काम कर सकता है।
// Usage: node extract.js input output
// where input (mandatory) is the text file containing your list of urls
// and output (optional) is the directory where the output files will be saved
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
// Read the command line parameters
var input = process.argv[2];
var output = process.argv[3];
if (!input) {
console.log("Missing input parameter");
return;
}
// Read the url input file, each url is on a new line
var urls = fs.readFileSync(input).toString().split('\n');
// Check for non urls and remove
for (var i = 0; i < urls.length; i++) {
if (urls[i].slice(0, 4) != 'http') {
urls.splice(i, 1);
}
}
// Iterate through the urls
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
// request function is asynchronous, hence requirement for self-executing function
// Cannot guarantee the execution order of the callback for each url, therefore save results to separate files
request(url, ( function(url) {
return function(err, resp, body) {
if (err)
throw err;
// Extract the pg parameter (book page) from the url
// We will use this to only extract the text from this book page
// because a retrieved html page contains multiple book pages
var pg = url.slice(url.indexOf('pg=') + 3, url.indexOf('&output=text'));
//
// Define the filename
//
var number = pg.slice(2, pg.length);
var zeroes = 4 - number.length;
// Insert leading zeroes
for (var j = 0; j < zeroes; j++) {
number = '0' + number;
}
var filename = pg.slice(0, 2) + number + '.txt';
// Add path to filename
if (output) {
if (!fs.existsSync(output))
fs.mkdirSync(output);
filename = output + '/' + filename;
}
// Delete the file if it already exists
if (fs.existsSync(filename))
fs.unlinkSync(filename);
// Make the DOM available to jquery
$ = cheerio.load(body);
// Select the book page
// Pages are contained within 'div' elements (where class='flow'),
// each of which contains an 'a' element where id is equal to the page
// Use ^ to match pages because sometimes page ids can have a trailing hyphen and extra characters
var page = $('div.flow:has(a[id=' + pg + ']), div.flow:has(a[id^=' + pg + '-])');
//
// Extract and save the text of the book page to the file
//
var hasText = false;
// Text is in 'gtxt_body', 'gtxt_column' and 'gtxt_footnote'
page.find('div.gtxt_body, div.gtxt_column, div.gtxt_footnote').each(function() {
this.find('p.gtxt_body, p.gtxt_column, p.gtxt_footnote').each(function() {
hasText = true;
fs.appendFileSync(filename, this.text());
fs.appendFileSync(filename, '\n\n');
});
});
// Log progress
if (hasText) {
console.log("Retrieved and saved page: " + pg);
}
else {
console.log("Skipping page: " + pg);
}
}
} )(url));
}