Hướng dẫn how do i scrape data from a website using javascript? - làm cách nào để thu thập dữ liệu từ một trang web bằng javascript?

JavaScript đã trở thành một trong những ngôn ngữ phổ biến và được sử dụng rộng rãi nhất do những cải tiến lớn mà nó đã thấy và giới thiệu thời gian chạy được gọi là NodeJS. Cho dù đó là một ứng dụng web hay di động, JavaScript hiện có các công cụ phù hợp. Bài viết này sẽ giải thích làm thế nào hệ sinh thái sôi động của NodeJS cho phép bạn xóa web một cách hiệu quả để đáp ứng hầu hết các yêu cầu của bạn.

Điều kiện tiên quyết

Bài đăng này chủ yếu nhằm vào các nhà phát triển có một số cấp độ kinh nghiệm với JavaScript. Tuy nhiên, nếu bạn có một sự hiểu biết vững chắc về việc quét web nhưng không có kinh nghiệm với JavaScript, nó vẫn có thể đóng vai trò giới thiệu ánh sáng cho JavaScript. Tuy nhiên, có kinh nghiệm trong các lĩnh vực sau đây chắc chắn sẽ giúp ích:

  • ✅ Kinh nghiệm với JavaScript
  • ✅ Trải nghiệm sử dụng các trình duyệt của trình duyệt để trích xuất các bộ chọn của các yếu tố
  • Một số kinh nghiệm với ES6 JavaScript (tùy chọn)

Đảm bảo kiểm tra các tài nguyên ở cuối bài viết này để biết thêm chi tiết về chủ đề này!

Kết quả

Sau khi đọc bài đăng này sẽ có thể:

  • Có một sự hiểu biết chức năng về nodejs
  • Sử dụng nhiều máy khách HTTP để hỗ trợ trong quy trình cạo Web
  • Sử dụng nhiều thư viện hiện đại và thử nghiệm chiến đấu để cạo web

Hiểu NodeJS: Giới thiệu ngắn gọn

JavaScript ban đầu có nghĩa là thêm các khả năng kịch bản thô sơ vào các trình duyệt, để cho phép các trang web hỗ trợ nhiều cách tương tác tùy chỉnh hơn với người dùng, như hiển thị hộp thoại hoặc tạo thêm nội dung HTML trên đường.

Với mục đích này, các trình duyệt đang cung cấp môi trường thời gian chạy (với các đối tượng toàn cầu như

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
8 và
const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
9) để cho phép mã của bạn tương tác với phiên bản trình duyệt và chính trang. Và trong hơn một thập kỷ, JavaScript thực sự bị giới hạn trong trường hợp sử dụng đó và trình duyệt. Tuy nhiên, điều đó đã thay đổi khi Ryan Dahl giới thiệu NodeJS vào năm 2009.Ryan Dahl introduced NodeJS in 2009.

Nodejs đã lấy động cơ JavaScript của Chrome và mang nó đến máy chủ (hoặc tốt hơn là dòng lệnh). Trái ngược với môi trường trình duyệt, nó không có thêm quyền truy cập vào cửa sổ trình duyệt hoặc lưu trữ cookie, nhưng thay vào đó, những gì nó có quyền truy cập đầy đủ vào tài nguyên hệ thống. Bây giờ, nó có thể dễ dàng mở kết nối mạng, lưu trữ hồ sơ trong cơ sở dữ liệu hoặc thậm chí chỉ đọc và ghi các tệp trên ổ cứng của bạn.

Về cơ bản, Node.js đã giới thiệu JavaScript làm ngôn ngữ phía máy chủ và cung cấp một công cụ JavaScript thông thường, được giải phóng khỏi xiềng xích hộp cát trình duyệt thông thường và thay vào đó, được bơm lên với một thư viện hệ thống tiêu chuẩn để kết nối mạng và truy cập tệp.

Vòng lặp sự kiện JavaScript

Những gì nó giữ, là vòng lặp sự kiện. Trái ngược với có bao nhiêu ngôn ngữ xử lý sự đồng thời, với nhiều luồng, JavaScript luôn chỉ sử dụng một luồng duy nhất và thực hiện các hoạt động chặn theo kiểu không đồng bộ, chủ yếu dựa vào các hàm gọi lại (hoặc con trỏ chức năng, như các nhà phát triển C có thể gọi chúng).

Hãy kiểm tra xem nhanh hơn với một ví dụ về máy chủ web đơn giản:

const http = require('http');
const PORT = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, () => {
  console.log(`Server running at PORT:${port}/`);
});

Ở đây, chúng tôi nhập thư viện tiêu chuẩn HTTP bằng

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
0, sau đó tạo một đối tượng máy chủ với
async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
1 và chuyển nó một hàm xử lý ẩn danh, thư viện sẽ gọi cho mỗi yêu cầu HTTP đến. Cuối cùng, chúng tôi
async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
2 trên cổng được chỉ định - và đó thực sự là nó.

Có hai bit thú vị ở đây và cả hai đã gợi ý về sự kiện của chúng tôi và sự không đồng bộ của JavaScript:

  1. Hàm xử lý mà chúng tôi chuyển sang
    async function fetch_demo()
    {
    	const resp = await fetch('https://www.reddit.com/r/programming.json');
    
    	console.log(await resp.json());
    }
    
    fetch_demo();
    
    1
  2. Thực tế là
    async function fetch_demo()
    {
    	const resp = await fetch('https://www.reddit.com/r/programming.json');
    
    	console.log(await resp.json());
    }
    
    fetch_demo();
    
    2 không phải là một cuộc gọi chặn, nhưng lại quay lại ngay lập tức

Trong hầu hết các ngôn ngữ khác, chúng tôi thường có hàm/phương thức ____25, sẽ chặn luồng của chúng tôi và trả về ổ cắm kết nối của máy khách kết nối. Tại thời điểm này, mới nhất, chúng tôi phải chuyển sang đa luồng, vì nếu không chúng tôi có thể xử lý chính xác một kết nối tại một thời điểm. Tuy nhiên, trong trường hợp này, chúng tôi không phải đối phó với quản lý chủ đề và chúng tôi luôn ở lại với một chủ đề, nhờ các cuộc gọi lại và vòng lặp sự kiện.

Như đã đề cập,

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
2 sẽ quay lại ngay lập tức, nhưng - mặc dù không có mã nào sau cuộc gọi
async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
2 của chúng tôi - ứng dụng sẽ không thoát ngay lập tức. Đó là bởi vì chúng tôi vẫn có một cuộc gọi lại đã đăng ký qua
async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
1 (chức năng chúng tôi đã vượt qua).

Bất cứ khi nào khách hàng gửi yêu cầu, Node.js sẽ phân tích nó trong nền và gọi chức năng ẩn danh của chúng tôi và chuyển đối tượng yêu cầu. Điều duy nhất chúng ta phải chú ý ở đây là nhanh chóng trở lại và không tự chặn chức năng, nhưng thật khó để làm điều đó, vì hầu như tất cả các cuộc gọi tiêu chuẩn đều không đồng bộ (thông qua các cuộc gọi lại hoặc lời hứa) - chỉ cần đảm bảo bạn không Chạy

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
9

Nhưng đủ lý thuyết, chúng ta hãy kiểm tra nó, phải không?

Nếu bạn đã cài đặt Node.js, tất cả những gì bạn cần làm là lưu mã vào tệp

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
0 và chạy nó trong shell của bạn với
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
1. Bây giờ, chỉ cần mở trình duyệt của bạn và tải http: // localhost: 3000 - voilà, bạn sẽ nhận được một lời chào "Xin chào thế giới" đáng yêu. Điều đó thật dễ dàng, phải không?

Người ta có thể cho rằng cách tiếp cận duy nhất có thể đi kèm với các vấn đề về hiệu suất, bởi vì nó chỉ có một chủ đề, nhưng nó thực sự hoàn toàn ngược lại và đó là vẻ đẹp của lập trình không đồng bộ. Lập trình đơn, không đồng bộ có thể có, đặc biệt là đối với công việc chuyên sâu I/O, khá nhiều lợi thế về hiệu suất, bởi vì người ta không cần phải phân bổ trước các tài nguyên (ví dụ: chủ đề).

Được rồi, đó là một ví dụ rất hay về cách chúng tôi dễ dàng tạo một máy chủ web trong Node.js, nhưng chúng tôi đang kinh doanh của Scraping, phải không? Vì vậy, chúng ta hãy xem các thư viện máy khách HTTP của JavaScript.

HTTP khách hàng: Truy vấn web

Các máy khách HTTP là các công cụ có khả năng gửi yêu cầu đến máy chủ và sau đó nhận được phản hồi từ nó. Hầu như mọi công cụ sẽ được thảo luận trong bài viết này đều sử dụng máy khách HTTP dưới mui xe để truy vấn máy chủ của trang web mà bạn sẽ cố gắng cạo.

1. Máy khách HTTP tích hợp

Như đã đề cập trong ví dụ máy chủ của bạn, Node.js không giao hàng theo mặc định với thư viện HTTP. Thư viện đó cũng có một máy khách HTTP tích hợp.

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();

Tuy nhiên, khá dễ dàng để bắt đầu, vì không có sự phụ thuộc của bên thứ ba nào để cài đặt hoặc quản lý, tuy nhiên - như bạn có thể nhận thấy từ ví dụ của chúng tôi - thư viện yêu cầu một chút nồi hơi, vì nó chỉ cung cấp phản hồi trong các khối và cuối cùng bạn cần phải khâu chúng lại với nhau bằng tay. Bạn cũng sẽ cần sử dụng một thư viện riêng cho URL HTTPS.

Nói tóm lại, nó thuận tiện vì nó xuất hiện, nhưng nó có thể yêu cầu bạn viết nhiều mã hơn bạn muốn. Do đó, chúng ta hãy xem các thư viện HTTP khác. Chúng ta sẽ?

2. Lấy API

Một phương pháp tích hợp khác sẽ là API tìm nạp.

Mặc dù các trình duyệt đã hỗ trợ nó trong một thời gian, nhưng nó mất nhiều thời gian hơn một chút, nhưng kể từ phiên bản 18, Node.js không hỗ trợ

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
2. Để công bằng, trong thời điểm hiện tại, nó vẫn được coi là một tính năng thử nghiệm, vì vậy nếu bạn thích chơi nó an toàn, bạn cũng có thể lựa chọn nút thư viện PolyFill/Wrapper, cung cấp chức năng tương tự.

Trong khi ở đó, cũng kiểm tra bài viết chuyên dụng của chúng tôi trên Node Fetch.

API tìm nạp sử dụng rất nhiều lời hứa và kết hợp với AIDIT, điều đó thực sự có thể cung cấp cho bạn mã nạc và dễ đọc.

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();

Cách giải quyết duy nhất chúng tôi phải sử dụng, là gói mã của chúng tôi thành một hàm, vì

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
3 chưa được hỗ trợ ở cấp cao nhất. Ngoài ra, chúng tôi thực sự chỉ gọi
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
2 với URL của chúng tôi, đã chờ phản hồi (dĩ nhiên, hứa hẹn xảy ra trong nền) và sử dụng chức năng
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
5 của đối tượng phản hồi của chúng tôi (đang chờ lại) để nhận phản hồi. Tâm trí bạn, một phản hồi đã được chia tay json.

Không tệ, hai dòng mã, không xử lý dữ liệu thủ công, không phân biệt giữa HTTP và HTTPS và đối tượng JSON gốc.

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
6 Tùy chọn chấp nhận một đối số tùy chọn bổ sung, trong đó bạn có thể tinh chỉnh yêu cầu của mình bằng một phương thức yêu cầu cụ thể (ví dụ:
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
7), các tiêu đề HTTP bổ sung hoặc thông tin xác thực vượt qua.

3. Axios

Axios khá giống với Fetch. Đây cũng là một máy khách HTTP dựa trên lời hứa và nó chạy ở cả hai, trình duyệt và node.js. Người dùng TypeScript cũng sẽ yêu thích hỗ trợ loại tích hợp của nó.

Tuy nhiên, một nhược điểm trái ngược với các thư viện mà chúng tôi đã đề cập cho đến nay, chúng tôi phải cài đặt nó trước.

Hoàn hảo, hãy xem một ví dụ điển hình đầu tiên:

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});

Khá đơn giản. Dựa vào những lời hứa, chúng tôi chắc chắn cũng có thể sử dụng

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
3 một lần nữa và làm cho toàn bộ điều ít dài hơn một chút. Vì vậy, hãy kết hợp nó thành một chức năng một lần nữa:

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}

Tất cả những gì bạn phải làm là gọi

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
9! Bạn có thể tìm thấy thư viện Axios tại GitHub.

4. Siêu nhân

Giống như Axios, Superagent là một ứng dụng khách HTTP mạnh mẽ khác có hỗ trợ cho những lời hứa và đường cú pháp Async/Await. Nó có một API khá đơn giản như Axios, nhưng Superagent có nhiều phụ thuộc hơn và ít phổ biến hơn.

Bất kể, thực hiện yêu cầu HTTP với Superagent bằng cách sử dụng lời hứa, Async/Await và các cuộc gọi lại trông như thế này:

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}

Bạn có thể tìm thấy thư viện Superagent tại GitHub và cài đặt Superagent đơn giản như

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
0.

Plugin Superagent

Một tính năng, tạo nên sự khác biệt so với các thư viện khác ở đây, là khả năng mở rộng của nó. Nó có khá nhiều danh sách các plugin cho phép điều chỉnh yêu cầu hoặc phản hồi. Ví dụ, plugin siêu nhiệt sẽ cho phép bạn xác định các quy tắc điều chỉnh cho các yêu cầu của bạn.

5. Yêu cầu

Mặc dù nó không được duy trì tích cực nữa, yêu cầu vẫn là một máy khách HTTP phổ biến và được sử dụng rộng rãi trong hệ sinh thái JavaScript.

Nó khá đơn giản để thực hiện yêu cầu HTTP với yêu cầu:

const request = require('request')
request('https://www.reddit.com/r/programming.json', function (
  error,
  response,
  body
) {
  console.error('error:', error)
  console.log('body:', body)
})

Những gì bạn chắc chắn sẽ nhận thấy ở đây, là chúng tôi không sử dụng những lời hứa đơn giản cũng như

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
3. Đó là bởi vì yêu cầu vẫn sử dụng phương pháp gọi lại truyền thống, tuy nhiên có một vài thư viện trình bao bọc để hỗ trợ chờ đợi.

Bạn có thể tìm thấy thư viện yêu cầu tại GitHub và cài đặt nó đơn giản như chạy

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
2.

Bạn có nên sử dụng yêu cầu không? Chúng tôi bao gồm yêu cầu trong danh sách này vì nó vẫn là một lựa chọn phổ biến. Tuy nhiên, sự phát triển đã chính thức dừng lại và nó không được duy trì tích cực nữa. Tất nhiên, điều đó không có nghĩa là nó không thể sử dụng được, và vẫn còn rất nhiều thư viện sử dụng nó, nhưng chính nó vẫn có thể khiến chúng ta suy nghĩ hai lần trước khi chúng ta sử dụng nó cho một dự án hoàn toàn mới, đặc biệt là với một danh sách khá Giải pháp thay thế và hỗ trợ

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
6 bản địa. We included Request in this list because it still is a popular choice. Nonetheless, development has officially stopped and it is not being actively maintained any more. Of course, that does not mean it is unusable, and there are still lots of libraries using it, but the fact itself, may still make us think twice before we use it for a brand-new project, especially with quite a list of viable alternatives and native
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
6 support.

Việc tìm nạp nội dung của một trang web, chắc chắn là một bước quan trọng trong bất kỳ dự án cạo nào, nhưng đó chỉ là bước đầu tiên và chúng tôi thực sự cần phải xác định và trích xuất dữ liệu. Đây là những gì chúng tôi sẽ kiểm tra tiếp theo, cách chúng tôi có thể xử lý một tài liệu HTML trong JavaScript và cách xác định và chọn thông tin để trích xuất dữ liệu.

Trước hết, các biểu thức chính quy 🙂

Biểu thức thông thường: Cách khó

Cách đơn giản nhất để bắt đầu với việc quét web mà không cần bất kỳ sự phụ thuộc nào, là sử dụng một loạt các biểu thức thông thường trên nội dung HTML bạn nhận được từ máy khách HTTP của mình. Nhưng có một sự đánh đổi lớn.

Mặc dù hoàn toàn tuyệt vời trong miền của họ, các biểu thức chính quy không lý tưởng cho các cấu trúc tài liệu phân tích cú pháp như HTML. Thêm vào đó, những người mới đến thường phải vật lộn với việc làm cho họ đúng ("Tôi có cần một cái nhìn trước hay nhìn không?"). Đối với việc quét web phức tạp, các biểu thức chính quy cũng có thể ra khỏi tầm tay. Như đã nói, dù sao chúng ta hãy cho nó đi.

Nói rằng có một nhãn với một số tên người dùng trong đó và chúng tôi muốn tên người dùng. Điều này tương tự như những gì bạn phải làm nếu bạn dựa vào các biểu thức thông thường:

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe

Chúng tôi đang sử dụng

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
4 ở đây, sẽ cung cấp cho chúng tôi một mảng chứa dữ liệu đánh giá biểu thức chính quy của chúng tôi. Khi chúng tôi sử dụng một nhóm bắt giữ (
async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
5), phần tử mảng thứ hai (
async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
6) sẽ chứa bất cứ điều gì nhóm đó quản lý để nắm bắt.

Mặc dù điều này chắc chắn làm việc trong ví dụ của chúng tôi, bất cứ điều gì phức tạp hơn sẽ không hoạt động hoặc sẽ yêu cầu một cách biểu hiện phức tạp hơn. Chỉ cần tưởng tượng bạn có một vài yếu tố

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
7 trong tài liệu HTML của bạn.

Đừng hiểu sai về chúng tôi, các biểu thức thông thường là một công cụ tuyệt vời không thể tưởng tượng được, không phải là HTML - vì vậy hãy để chúng tôi giới thiệu cho bạn thế giới của các bộ chọn CSS và DOM.

Cheerio: Core JQuery để đi qua DOM

Cheerio là một thư viện hiệu quả và nhẹ, cho phép bạn sử dụng API phong phú và mạnh mẽ của jQuery ở phía máy chủ. Nếu bạn đã sử dụng jQuery trước đây, bạn sẽ cảm thấy như ở nhà với Cheerio. Nó cung cấp cho bạn một cách cực kỳ dễ dàng để phân tích chuỗi HTML vào cây dom, sau đó bạn có thể truy cập thông qua giao diện thanh lịch mà bạn có thể quen thuộc từ jQuery (bao gồm cả chuỗi chức năng).

const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

Như bạn có thể thấy, sử dụng Cheerio thực sự gần giống với cách bạn sử dụng jQuery.

Hãy nhớ rằng, Cheerio thực sự tập trung vào việc điều khiển Dom và bạn sẽ không thể trực tiếp "chức năng jQuery" cổng ", chẳng hạn như yêu cầu XHR/AJAX hoặc xử lý chuột (ví dụ:

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
8), một-một trong Cheerio.

Cheerio là một công cụ tuyệt vời cho hầu hết các trường hợp sử dụng khi bạn cần tự xử lý DOM. Tất nhiên, nếu bạn muốn thu thập thông tin về một trang web nặng JavaScript (ví dụ: các ứng dụng một trang điển hình), bạn có thể cần một cái gì đó gần hơn với một công cụ trình duyệt đầy đủ. Chúng ta sẽ nói về điều đó chỉ trong giây lát, dưới các trình duyệt không đầu trong JavaScript.

Thời gian cho một ví dụ vui chơi nhanh chóng, bạn sẽ không đồng ý? Để chứng minh sức mạnh của Cheerio, chúng tôi sẽ cố gắng thu thập dữ liệu diễn đàn R/Lập trình trong Reddit và nhận được danh sách các tên bài đăng.

Đầu tiên, cài đặt Cheerio và Axios bằng cách chạy lệnh sau:

async function getForum() {
	try {
		const response = await axios.get(
			'https://www.reddit.com/r/programming.json'
		)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
9.

Sau đó tạo một tệp mới có tên

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
0 và sao chép/dán mã sau:

const axios = require('axios');
const cheerio = require('cheerio');

const getPostTitles = async () => {
	try {
		const { data } = await axios.get(
			'https://old.reddit.com/r/programming/'
		);
		const $ = cheerio.load(data);
		const postTitles = [];

		$('div > p.title > a').each((_idx, el) => {
			const postTitle = $(el).text()
			postTitles.push(postTitle)
		});

		return postTitles;
	} catch (error) {
		throw error;
	}
};

getPostTitles()
    .then((postTitles) => console.log(postTitles));

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
1 là một chức năng không đồng bộ sẽ thu thập dữ liệu diễn đàn lập trình Subreddit R/. Đầu tiên, HTML của trang web được lấy bằng cách sử dụng yêu cầu HTTP đơn giản với thư viện máy khách AXIOS HTTP. Sau đó, dữ liệu HTML được đưa vào Cheerio bằng hàm
const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
2.

Thật tuyệt vời, bây giờ chúng tôi đã phân tích hoàn toàn tài liệu HTML là Dom Tree, tốt kiểu cũ, trong

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
3. Cái gì tiếp theo? Chà, có thể không phải là một ý tưởng tồi để biết nơi để có được các tiêu đề đăng bài của chúng tôi. Vì vậy, hãy nhấp chuột phải vào một trong những tiêu đề và chọn
const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
4. Điều đó sẽ giúp chúng tôi đúng với yếu tố phù hợp trong các công cụ nhà phát triển của trình duyệt.

Hướng dẫn how do i scrape data from a website using javascript? - làm cách nào để thu thập dữ liệu từ một trang web bằng javascript?

Tuyệt vời, được trang bị kiến ​​thức của chúng tôi về các bộ chọn XPath hoặc CSS, giờ đây chúng tôi có thể dễ dàng soạn thảo biểu thức mà chúng tôi cần cho yếu tố đó. Ví dụ của chúng tôi, chúng tôi đã chọn bộ chọn CSS và theo dõi một người chỉ hoạt động đẹp.

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
0

Nếu bạn đã sử dụng jQuery, có lẽ bạn sẽ biết những gì chúng ta đang làm, phải không? 😏

Bạn đã hoàn toàn đúng. Cuộc gọi của Cheerio giống hệt với jQuery (có một lý do tại sao chúng tôi đã sử dụng

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
3 cho biến DOM của chúng tôi trước đây) và sử dụng Cheerio với bộ chọn CSS của chúng tôi sẽ cung cấp cho chúng tôi danh sách các yếu tố phù hợp với bộ chọn của chúng tôi.

Bây giờ, chúng ta chỉ cần lặp lại với

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
6 trên tất cả các yếu tố và gọi chức năng
const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
7 của chúng để có được nội dung văn bản của chúng. 💯 JQuery, phải không?

Rất nhiều về lời giải thích. Thời gian để chạy mã của chúng tôi.

Mở vỏ của bạn và chạy

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
8. Sau đó, bạn sẽ thấy một mảng khoảng 25 hoặc 26 tiêu đề bài viết khác nhau (nó sẽ khá dài). Mặc dù đây là một trường hợp sử dụng đơn giản, nó thể hiện bản chất đơn giản của API do Cheerio cung cấp.

Nếu trường hợp sử dụng của bạn yêu cầu thực hiện JavaScript và tải các nguồn bên ngoài, một vài tùy chọn sau đây sẽ hữu ích.

JSdom: DOM cho nút

Tương tự như cách Cheerio sao chép jQuery ở phía máy chủ, JSDOM cũng làm điều tương tự cho chức năng DOM gốc của trình duyệt.

Tuy nhiên, không giống như Cheerio, JSdom không chỉ phân tích HTML vào cây dom, nó còn có thể xử lý mã JavaScript nhúng và nó cho phép bạn "tương tác" với các yếu tố trang.

Việc khởi tạo một đối tượng JSdom khá dễ dàng:

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
1

Ở đây, chúng tôi đã nhập thư viện với

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
0 và tạo một thể hiện JSdom mới bằng cách sử dụng hàm tạo và truyền đoạn trích HTML của chúng tôi. Sau đó, chúng tôi chỉ cần sử dụng
const request = require('request')
request('https://www.reddit.com/r/programming.json', function (
  error,
  response,
  body
) {
  console.error('error:', error)
  console.log('body:', body)
})
0 (như chúng tôi biết từ phát triển mặt trước) để chọn phần tử của chúng tôi và điều chỉnh các thuộc tính của nó một chút. Tất nhiên, khá chuẩn và chúng tôi cũng có thể làm điều đó với Cheerio.

Tuy nhiên, điều đặt ra JSdom, ngoài việc hỗ trợ đã nói ở trên cho mã JavaScript nhúng và, rằng, chúng tôi sẽ kiểm tra ngay bây giờ.

Ví dụ sau sử dụng trang HTML cục bộ đơn giản, với một nút thêm

const request = require('request')
request('https://www.reddit.com/r/programming.json', function (
  error,
  response,
  body
) {
  console.error('error:', error)
  console.log('body:', body)
})
1 với ID.

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
2

Không có gì quá phức tạp ở đây:

  • Chúng tôi
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    2 JSdom
  • Thiết lập tài liệu
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    3 của chúng tôi
  • Chuyển
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    3 cho hàm tạo JSdom của chúng tôi (quan trọng, chúng tôi cần bật
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    5)
  • Chọn nút có cuộc gọi
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    0
  • const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    7 nó

Voilà, điều đó sẽ cho chúng ta đầu ra này

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
3

Khá đơn giản và ví dụ đã trình bày cách chúng ta có thể sử dụng JSdom để thực sự thực hiện mã JavaScript của trang. Khi chúng tôi tải tài liệu, ban đầu không có

const request = require('request')
request('https://www.reddit.com/r/programming.json', function (
  error,
  response,
  body
) {
  console.error('error:', error)
  console.log('body:', body)
})
1. Chỉ khi chúng tôi nhấp vào nút, nó đã được thêm vào mã của trang web, chứ không phải mã trình thu thập dữ liệu của chúng tôi.

Trong bối cảnh này, các chi tiết quan trọng là

const request = require('request')
request('https://www.reddit.com/r/programming.json', function (
  error,
  response,
  body
) {
  console.error('error:', error)
  console.log('body:', body)
})
5 và
const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
0. Những cờ này hướng dẫn JSdom chạy mã của trang, cũng như tìm nạp bất kỳ tệp JavaScript có liên quan nào. Như tài liệu của JSdom chỉ ra, điều đó có khả năng cho phép bất kỳ trang web nào thoát khỏi hộp cát và truy cập vào hệ thống địa phương của bạn, chỉ bằng cách thu thập dữ liệu. Hãy tiến hành thận trọng.Proceed with caution please.

JSDOM là một thư viện tuyệt vời để xử lý hầu hết các tác vụ trình duyệt điển hình trong ví dụ Node.js cục bộ của bạn, nhưng nó vẫn có một số hạn chế và đó là nơi các trình duyệt không đầu thực sự tỏa sáng.

Chúng tôi đã phát hành một tính năng mới giúp toàn bộ quá trình này đơn giản hơn. Bây giờ bạn có thể trích xuất dữ liệu từ HTML với một cuộc gọi API đơn giản. Hãy kiểm tra tài liệu ở đây.

Trình duyệt không đầu trong JavaScript

Các trang web ngày càng trở nên phức tạp hơn và thường xuyên thu thập dữ liệu HTTP thường xuyên sẽ không đủ nữa, nhưng người ta thực sự cần một động cơ trình duyệt đầy đủ, để có được thông tin cần thiết từ một trang web.

Điều này đặc biệt đúng đối với các spa dựa nhiều vào JavaScript và các tài nguyên năng động và không đồng bộ.

Tự động hóa trình duyệt và trình duyệt không đầu đến giải cứu ở đây. Hãy xem cách họ có thể giúp chúng tôi dễ dàng thu thập các ứng dụng một trang và các trang web khác sử dụng JavaScript.

1. Puffeteer: Trình duyệt không đầu

Puppeteer, như tên gọi, cho phép bạn thao tác với trình duyệt một cách lập trình, giống như cách một con rối sẽ được điều khiển bởi người múa rối của nó. Nó đạt được điều này bằng cách cung cấp cho nhà phát triển API cấp cao để kiểm soát phiên bản Chrome không đầu theo mặc định và có thể được cấu hình để chạy không đầu.

Hướng dẫn how do i scrape data from a website using javascript? - làm cách nào để thu thập dữ liệu từ một trang web bằng javascript?
Lấy từ các tài liệu Puppeteer (nguồn)

Puppeteer đặc biệt hữu ích hơn các công cụ đã nói ở trên vì nó cho phép bạn thu thập dữ liệu trên web như thể một người thực sự đang tương tác với trình duyệt. Điều này mở ra một vài khả năng không có ở đó trước đây:

  • Bạn có thể nhận được ảnh chụp màn hình hoặc tạo tệp PDF của các trang.
  • Bạn có thể thu thập một ứng dụng trang duy nhất và tạo nội dung được kết xuất sẵn.
  • Bạn có thể tự động hóa nhiều tương tác người dùng khác nhau, như đầu vào bàn phím, biểu mẫu bài nộp, điều hướng, v.v.

Nó cũng có thể đóng một vai trò lớn trong nhiều nhiệm vụ khác ngoài phạm vi thu thập dữ liệu web như kiểm tra UI, hỗ trợ tối ưu hóa hiệu suất, v.v.

Rất thường xuyên, bạn có thể sẽ muốn chụp ảnh màn hình của các trang web hoặc, để biết về danh mục sản phẩm của đối thủ cạnh tranh. Puppeteer có thể được sử dụng để làm điều này. Để bắt đầu, hãy cài đặt Puppeteer bằng cách chạy lệnh sau:

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
1

Điều này sẽ tải xuống một phiên bản crom đi kèm, chiếm khoảng 180 đến 300 MB, tùy thuộc vào hệ điều hành của bạn. Bạn có thể tránh bước đó và sử dụng thiết lập đã được cài đặt, bằng cách chỉ định một vài biến môi trường múa rối, chẳng hạn như

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
2. Mặc dù vậy, nhìn chung, Puppeteer khuyến nghị sử dụng phiên bản đi kèm và không hỗ trợ các thiết lập tùy chỉnh.

Hãy cố gắng lấy ảnh chụp màn hình và pdf của diễn đàn R/Lập trình trong Reddit, tạo một tệp mới có tên

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
0 và sao chép/dán mã sau:

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
4

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
4 là một chức năng không đồng bộ sẽ chụp ảnh màn hình của trang của chúng tôi, cũng như xuất nó dưới dạng tài liệu PDF.

Để bắt đầu, một thể hiện của trình duyệt được tạo bằng cách chạy

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
5. Tiếp theo, chúng tôi tạo một tab/trang trình duyệt mới với
const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
6. Bây giờ, chúng tôi chỉ cần gọi
const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
7 trên thể hiện trang của chúng tôi và truyền URL của chúng tôi.

Tất cả các chức năng này đều có tính chất không đồng bộ và sẽ quay trở lại ngay lập tức, nhưng khi chúng trả lại lời hứa của JavaScript và chúng tôi đang sử dụng

const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
3, dòng chảy vẫn có vẻ đồng bộ và do đó, một khi
const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
9 được trả về ", trang web của chúng tôi nên được tải.

Tuyệt vời, chúng tôi đã sẵn sàng để có được những bức ảnh đẹp. Chúng ta hãy gọi

const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

0 trên thể hiện trang của chúng tôi và chuyển nó một đường dẫn đến tệp hình ảnh của chúng tôi. Chúng tôi làm tương tự với
const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

1 và voilà, chúng tôi nên có tại các vị trí được chỉ định hai tệp mới. Bởi vì chúng tôi có trách nhiệm cư dân mạng, chúng tôi cũng gọi
const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

2 trên đối tượng Trình duyệt của chúng tôi, để dọn dẹp phía sau chính mình. Đó là nó.

Một lần cần ghi nhớ, khi

const htmlString = ''
const result = htmlString.match(/)

console.log(result[1])
// John Doe
7 trả về, trang đã được tải nhưng nó có thể không được thực hiện với tất cả các tải không đồng bộ của nó. Vì vậy, tùy thuộc vào trang web của bạn, bạn có thể muốn thêm logic bổ sung vào trình thu thập dữ liệu sản xuất, để chờ một số sự kiện JavaScript hoặc các thành phần DOM nhất định.

Nhưng hãy chạy mã. Bật lên một cửa sổ shell, nhập

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
8 và sau một vài khoảnh khắc, bạn nên có chính xác hai tệp được đề cập trong thư mục của mình.

Đó là một công cụ tuyệt vời và nếu bạn thực sự quan tâm đến nó bây giờ, xin vui lòng xem các hướng dẫn khác của chúng tôi về Puppeteer.

  • Cách tải xuống một tệp với Puppeteer
  • Xử lý và gửi các mẫu HTML với Puppeteer
  • Sử dụng Puppeteer với Python và Pyppeteer

2. Nightmare: Một sự thay thế cho Puppeteer

Nightmare là một thư viện tự động hóa trình duyệt cấp cao như Puppeteer. Nó sử dụng electron và web và điểm chuẩn cào cho thấy nó cho thấy hiệu suất tốt hơn đáng kể so với phantomjs tiền nhiệm của nó. Nếu Puppeteer quá phức tạp cho trường hợp sử dụng của bạn hoặc có vấn đề với gói crom mặc định, Nightmare - mặc dù tên của nó - có thể chỉ là điều đúng đắn cho bạn.

Như thường lệ, hành trình của chúng tôi bắt đầu với NPM:

const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

5

Khi Nightmare có sẵn trên hệ thống của bạn, chúng tôi sẽ sử dụng nó để tìm trang web của ScrapingBee thông qua tìm kiếm dũng cảm. Để làm như vậy, hãy tạo một tệp có tên

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
0 và sao chép/dán mã sau vào đó:

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
5

Sau khi nhập thư viện thông thường với

async function fetch_demo()
{
	const resp = await fetch('https://www.reddit.com/r/programming.json');

	console.log(await resp.json());
}

fetch_demo();
0, trước tiên chúng tôi tạo ra một ví dụ mới về cơn ác mộng và lưu nó trong
const cheerio = require('cheerio')
const $ = cheerio.load('

Hello world

'
) $('h2.title').text('Hello there!') $('h2').addClass('welcome') $.html() //

Hello there!

8. Sau đó, chúng tôi sẽ có rất nhiều niềm vui với chuỗi chức năng và lời hứa 🥳

  1. Chúng tôi sử dụng
    const htmlString = ''
    const result = htmlString.match(/)
    
    console.log(result[1])
    // John Doe
    
    7 để tải dũng cảm từ https://search.brave.com
  2. Chúng tôi
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    0 Thuật ngữ tìm kiếm của chúng tôi "ScrapingBee" trong đầu vào tìm kiếm của Brave, với bộ chọn CSS
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    1 (Brave khá đơn giản với việc đặt tên của nó, phải không?)
  3. Chúng tôi
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    2 nút gửi để bắt đầu tìm kiếm của chúng tôi. Một lần nữa, đó là với bộ chọn CSS
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    3 (Brave thực sự đơn giản, chúng tôi yêu thích điều đó)really straightforward, we love that❣️)
  4. Hãy nghỉ ngơi nhanh chóng, cho đến khi Brave trả lại danh sách tìm kiếm.
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    4, với bộ chọn phù hợp làm việc kỳ diệu ở đây.
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    4 cũng chấp nhận giá trị thời gian, nếu bạn cần đợi trong một khoảng thời gian cụ thể.
  5. Khi Nightmare có danh sách liên kết từ Brave, chúng tôi chỉ cần sử dụng
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    6 để chạy mã tùy chỉnh của chúng tôi trên trang (trong trường hợp này là
    const request = require('request')
    request('https://www.reddit.com/r/programming.json', function (
      error,
      response,
      body
    ) {
      console.error('error:', error)
      console.log('body:', body)
    })
    
    0) và nhận phần tử
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    8 đầu tiên khớp với bộ chọn của chúng tôi và trả về thuộc tính
    const axios = require('axios');
    const cheerio = require('cheerio');
    
    const getPostTitles = async () => {
    	try {
    		const { data } = await axios.get(
    			'https://old.reddit.com/r/programming/'
    		);
    		const $ = cheerio.load(data);
    		const postTitles = [];
    
    		$('div > p.title > a').each((_idx, el) => {
    			const postTitle = $(el).text()
    			postTitles.push(postTitle)
    		});
    
    		return postTitles;
    	} catch (error) {
    		throw error;
    	}
    };
    
    getPostTitles()
        .then((postTitles) => console.log(postTitles));
    
    9 của nó.
  6. Cuối cùng nhưng không kém phần quan trọng, chúng tôi gọi
    const http = require('http');
    
    const req = http.request('http://example.com', res => {
    	const data = [];
    
    	res.on('data', _ => data.push(_))
    	res.on('end', () => console.log(data.join()))
    });
    
    req.end();
    
    00 để chạy và hoàn thành hàng đợi nhiệm vụ của chúng tôi.

Đó là nó, các bạn.

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
00 trả về một lời hứa tiêu chuẩn với giá trị từ cuộc gọi của chúng tôi đến
const axios = require('axios');
const cheerio = require('cheerio');

const getPostTitles = async () => {
	try {
		const { data } = await axios.get(
			'https://old.reddit.com/r/programming/'
		);
		const $ = cheerio.load(data);
		const postTitles = [];

		$('div > p.title > a').each((_idx, el) => {
			const postTitle = $(el).text()
			postTitles.push(postTitle)
		});

		return postTitles;
	} catch (error) {
		throw error;
	}
};

getPostTitles()
    .then((postTitles) => console.log(postTitles));
6. Tất nhiên, bạn cũng có thể sử dụng
const axios = require('axios')

axios
	.get('https://www.reddit.com/r/programming.json')
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	});
3 ở đây.

Điều đó khá dễ dàng, không phải là? Và nếu mọi thứ đều ổn 🤞, giờ đây chúng ta nên có liên kết đến trang web của ScrapingBee tại https://www.scrapingbee.com

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
6

Muốn tự mình thử? Chỉ cần chạy

const superagent = require("superagent")
const forumURL = "https://www.reddit.com/r/programming.json"

// callbacks
superagent
	.get(forumURL)
	.end((error, response) => {
		console.log(response)
	})

// promises
superagent
	.get(forumURL)
	.then((response) => {
		console.log(response)
	})
	.catch((error) => {
		console.error(error)
	})

// promises with async/await
async function getForum() {
	try {
		const response = await superagent.get(forumURL)
		console.log(response)
	} catch (error) {
		console.error(error)
	}
}
8 trong vỏ của bạn 👍

3. Nhà viết kịch, Khung quét web mới

Nhà viết kịch là khung không có đầu nền, đa nền tảng mới được Microsoft hỗ trợ.

Ưu điểm chính của nó so với Puppeteer là nó là nền tảng chéo và rất dễ sử dụng.

Dưới đây là cách chỉ cần cạo một trang với nó:

const http = require('http');

const req = http.request('http://example.com', res => {
	const data = [];

	res.on('data', _ => data.push(_))
	res.on('end', () => console.log(data.join()))
});

req.end();
7

Hãy kiểm tra hướng dẫn nhà viết kịch của chúng tôi nếu bạn muốn tìm hiểu thêm.

Bản tóm tắt

Phew, đó là một bài đọc dài! Nhưng chúng tôi hy vọng, các ví dụ của chúng tôi đã quản lý để cung cấp cho bạn cái nhìn đầu tiên về thế giới cào trên web với JavaScript và thư viện nào bạn có thể sử dụng để thu thập thông tin và xóa thông tin bạn cần.

Hãy cho nó một bản tóm tắt nhanh chóng, những gì chúng ta đã học được hôm nay là:

  • NodeJS là thời gian chạy JavaScript cho phép JavaScript được chạy phía máy chủ. Nó có một bản chất không chặn nhờ vòng lặp sự kiện.NodeJS is a JavaScript runtime that allow JavaScript to be run server-side. It has a non-blocking nature thanks to the Event Loop.
  • Các máy khách HTTP, chẳng hạn như Libaries và Fetch, cũng như Axios, Superagent, Node Fetch và Yêu cầu, được sử dụng để gửi các yêu cầu HTTP đến máy chủ và nhận phản hồi.HTTP clients, such as the native libaries and fetch, as well as Axios, SuperAgent, node-fetch, and Request, are used to send HTTP requests to a server and receive a response.
  • ✅ Cheerio trừu tượng hóa tốt nhất trong JQuery cho mục đích duy nhất là chạy phía máy chủ CNTT để thu thập thông tin web nhưng không thực thi mã JavaScript.Cheerio abstracts the best out of jQuery for the sole purpose of running it server-side for web crawling but does not execute JavaScript code.
  • JSDOM tạo một DOM theo thông số kỹ thuật JavaScript tiêu chuẩn từ chuỗi HTML và cho phép bạn thực hiện các thao tác DOM trên đó.JSDOM creates a DOM per the standard JavaScript specification out of an HTML string and allows you to perform DOM manipulations on it.
  • Puppeteer và Nightmare là các thư viện tự động hóa trình duyệt cấp cao, cho phép bạn điều khiển các ứng dụng web như thể một người thực sự đang tương tác với chúng.Puppeteer and Nightmare are high-level browser automation libraries, that allow you to programmatically manipulate web applications as if a real person were interacting with them.

Bài viết này tập trung vào hệ sinh thái cạo của JavaScript và các công cụ của nó. Tuy nhiên, chắc chắn cũng có các apsects khác để cạo, mà chúng ta không thể bao gồm trong bối cảnh này.

Ví dụ, các trang web thường sử dụng các kỹ thuật để nhận biết và chặn các trình thu thập thông tin. Bạn sẽ muốn tránh những thứ này và hòa nhập như khách truy cập bình thường. Về chủ đề này, và hơn thế nữa, chúng tôi có một hướng dẫn tận tâm, tuyệt vời về cách không bị chặn như một người thu thập thông tin. Xin vui lòng kiểm tra nó.Check it out please.

💡 Bạn nên yêu thích cào, nhưng những hạn chế về thời gian thông thường cho dự án của bạn không cho phép bạn điều chỉnh sự hoàn hảo của các trình thu thập thông tin, sau đó xin vui lòng xem nền tảng API cạo của chúng tôi. Scrapingbee được xây dựng với tất cả những điều này trong tâm trí và đã trở lại trong tất cả các nhiệm vụ bò.

Hạnh phúc cào!

Tài nguyên

Bạn có muốn đọc nhiều hơn không? Kiểm tra các liên kết sau:

  • Trang web NodeJS - Trang web chính của NodeJS với tài liệu chính thức của nó.
  • Tài liệu của Puppeteer - Tài liệu về Puppeteer của Google, với việc bắt đầu hướng dẫn và tham chiếu API.
  • Playright - Một giải pháp thay thế cho Puppeteer, được hỗ trợ bởi Microsoft.
  • Blog của ScrapingBee - chứa nhiều thông tin về các tính năng quét web trên nhiều nền tảng.
  • Xử lý cuộn vô hạn với Puppeteer
  • Node -Unblocker - Gói Node.js để tạo điều kiện cho Web Scraping qua các proxy.+

Bạn có thể cạo một trang web với JavaScript không?

Xóa web với JavaScript là một kỹ thuật rất hữu ích để trích xuất dữ liệu từ Internet để trình bày hoặc phân tích..

Làm cách nào để xóa dữ liệu cụ thể từ một trang web?

Quá trình cạo dữ liệu web..
Xác định trang web mục tiêu ..
Thu thập URL của các trang mà bạn muốn trích xuất dữ liệu từ ..
Yêu cầu các URL này để nhận HTML của trang ..
Sử dụng trình định vị để tìm dữ liệu trong HTML ..
Lưu dữ liệu trong tệp JSON hoặc CSV hoặc một số định dạng có cấu trúc khác ..

Có thể sử dụng cào web để rút dữ liệu ra khỏi các trang web không?

Các ứng dụng cạo web (hoặc 'bot') được lập trình để truy cập các trang web, lấy các trang có liên quan và trích xuất thông tin hữu ích.Bằng cách tự động hóa quá trình này, các bot này có thể trích xuất một lượng dữ liệu khổng lồ trong một thời gian rất ngắn.By automating this process, these bots can extract huge amounts of data in a very short time.

Làm cách nào để xóa dữ liệu từ một trang web bằng Node JS?

Cách cạo một trang web trong nút bằng cách sử dụng Cheerio..
Bước 1 - Tạo một thư mục làm việc.....
Bước 2 - Khởi tạo dự án.....
Bước 3 - Cài đặt phụ thuộc.....
Bước 4 - Kiểm tra trang web bạn muốn cạo.....
Bước 5 - Viết mã để xóa dữ liệu ..