Asked Aug 24th, 2017 2:13 PM 2392 5 1
  • 2392 5 1
+5

[NODEJS] LÀM SAO LẤY DỮ LIỆU TỪ WEBSITE CÓ SỬ DỤNG AJAX BẰNG NODEJS

Share
  • 2392 5 1

Hello các thành viên trong nhóm, mình là thành viên đã và đang nghiên cứu về Nodejs. Hôm nay mình có một vấn đề muốn hỏi các pác là: Mình sử dụng Nodejs muốn lấy dữ liệu từ website khác, nhưng có vấn đề là website mình muốn lấy nó load hình ảnh, dữ liệu bằng ajax. Vậy thì mình phải làm sao lấy được dữ liệu khi trang load ajax, các bác có cách nào giúp mình với nhé. Mình xin chia sẻ thêm là mình đang muốn lấy dữ liệu của chi tiết sản phảm của Tmall, trong trang này có phần chi tiết hình ảnh họ sử dụng lazy load để load hỉnh ảnh ra. Mình đang tính viết ứng dụng để lấy hết hình ảnh về bằng Nodejs. Bạn giúp mình với. Đây là trang demo: https://goo.gl/w1jXXc

Thanks all!!!😘😘😘😘

1 ANSWERS


Answered Aug 24th, 2017 4:24 PM
Accepted
+6

Chào bạn! Với những trang web phức tạp như này thì mình nghĩ nên sử dụng headless browser để lấy dữ liệu. Mình chia thành 2 phần cho dễ theo dõi nhé 😄 1. Giới thiệu chung

  • Theo kiến thức hạn hẹp mình biết thì hiện nay có 2 cách lấy dữ liệu web tự động (trộm) chính đó là:
    • Phương pháp sử dụng request (Request base method): Phù hợp với trang web tĩnh, ít sử dụng ajax, url đối tượng cần get có thể đoán được (?page=1, ?image=2, ...)
    • Phương pháp sử dụng trình duyệt (Browser base method): Áp dụng với trang web động, sử dụng nhiều ajax, đôi tượng cần get rất khó đoán được (do generate từ minified JS ra)
  • Trong phạm vi câu hỏi mình sẽ giới thiệu về phương pháp thứ 2. Sở dĩ được gọi là headless browser bởi vì thứ nhất nó là 1 browser, thứ 2 là nó có thể chạy mà không cần tới giao diện người dùng (UI). Bạn có thể điều khiển headless browser thông qua API mà nó cung cấp.
  • Với NodeJS thì có một số tên tuổi đình đám sử dụng Chrominum như:
  • Còn sử dụng Firefox thì có
  • Công dụng chính của headless browser: Để tự động hóa các tác vụ trên trình duyệt (test UI, lấy dữ liệu,...)

2. Bắt tay vào làm nào

  • Mấy thư viện trên gần như tương tự nhau về mặt chức năng. Mình thì thích API của Puppeteer hơn vì nó sinh sau đẻ muộn và cú pháp nó gắn gọn hơn. Bạn setup theo hướng dẫn tại đây https://github.com/GoogleChrome/puppeteer
  • Phương châm khi lấy dữ liệu bằng headless browser đó là: "thấy được lấy được" 😃)
  • Ok mình demo lấy 5 cái ảnh to sản phẩm ở link này cho bạn (https://world.tmall.com/item/543285442762.htm). Điểm khó ở đây đó chính là 5 ảnh này chỉ xuất hiện sau khi mình hover => JS sẽ xử lý sự kiện => chạy ajax để lấy ảnh về. Với cách lấy dữ liệu sử dụng cURL thì việc này gần như là bất khả thi vì phải decode 1 đống JS đã minify để xem logic lấy URL ảnh kiểu gì. Do đó chúng ta nên dùng headless browser.
  • Loay hoay mãi cũng ra. Mình comment trong code luôn cho bạn dễ hình dung nhé.
  • Chạy
$ node index.js
  • Và đây là kết quả trên console
  'https://img.alicdn.com/imgextra/i3/1695308781/TB2wkICt9hlpuFjSspkXXa1ApXa_!!1695308781.jpg_430x430q90.jpg',
  'https://img.alicdn.com/imgextra/i2/1695308781/TB2uwGFb88kpuFjSspeXXc7IpXa_!!1695308781.jpg_430x430q90.jpg',
  'https://img.alicdn.com/imgextra/i4/1695308781/TB2kzeCb80kpuFjy1XaXXaFkVXa_!!1695308781.jpg_430x430q90.jpg',
  'https://img.alicdn.com/imgextra/i3/1695308781/TB2AouUeYBmpuFjSZFAXXaQ0pXa_!!1695308781.jpg_430x430q90.jpg' ]

Chúc bạn thành công! 😸

Share
Tu Nguyen @qaqeqe0
Aug 24th, 2017 10:15 PM

Rất cảm ơn @Trần Duy Khánh ! Bạn hay quá, nhờ bạn mà mình biết thêm nhiều kiến thức và kỹ năng, mình biết thêm cách lấy hình ảnh nổi bật của thằng Tmall. Nhưng thực ra mới đầu mình mình cần lấy hình ảnh ở dưới phần description vì hình dưới đây size lớn và nhiều. Nó nằm trong cặp thẻ này

... ... ...

Nhưng nhờ bạn mình cũng đã biết nó có sẵn trong code luôn rồi, nó không phải load bằng ajax, chỉ là nó dùng jquery thay thế 2 thuộc tính src và data-ks-lazyload

Mình cũng xin lỗi vì mình không thêm dòng code HTML trở thành dòng code vì mình là thành viên mới nên chưa biết nhiều. Có gì bác chỉ dạy mình thêm nha.

Cảm ơn bác nhiều nhé!

Tiện thể bác cho mình hỏi thêm là mình muốn lấy hết dữ liệu và nén tất cả vào file .zip và tải về thì mình phải làm sao?

Một lần nữa mình xin cảm ơn chân thành.

0
| Reply
Share
Thang Tran Duc @thangtd90
Aug 25th, 2017 12:35 AM

@qaqeqe0

Mình cũng xin lỗi vì mình không thêm dòng code HTML trở thành dòng code vì mình là thành viên mới nên chưa biết nhiều. Có gì bác chỉ dạy mình thêm nha.

Viblo sử dụng cú pháp Markdown để format bài viết. Bạn có thể tham khảo thêm ở đây :slight_smile: https://viblo.asia/helps/cach-su-dung-markdown-bxjvZYnwkJZ

Ngoài ra bạn cũng có thể tìm hiểu thêm về các chức năng chính của Viblo tại đây nhé 😃

0
| Reply
Share
Aug 25th, 2017 12:55 AM

@qaqeqe0 Đã có link ảnh rồi thì lấy về rất đơn giản. Bạn có thể:

😃

+1
| Reply
Share
Tu Nguyen @qaqeqe0
Aug 25th, 2017 1:40 AM

Rất cảm ơn bác!! Xin chân thành cảm ơn và hậu tạ :) :)

0
| Reply
Share
Tu Nguyen @qaqeqe0
Aug 26th, 2017 5:10 AM

Hello anh Duy Khánh! Em xin làm phiền anh một lần này nữa nhé! Cũng là vấn đề này, sau khi nhận được sự giúp đỡ của anh em liền tìm hiểu cách của anh nhưng không được, mấy ngày hôm nay em tìm đủ mọi cách để lấy url hình ảnh trong thuộc tính data-ks-lazyload:

<div id="description" class="J_DetailSection tshop-psm tshop-psm-bdetaildes">
    <h4 class="hd">商品详情</h4>
    <div class="content ke-post" style="height: auto;">
  ....
    <p>
            <a href="https://taoquan.taobao.com/coupon/unify_apply.htm?sellerId=1695308781&amp;activityId=b22502e1e84b4086a18d1e01eeb2e203" target="_blank">
                <img alt="" src="//img-tmdetail.alicdn.com/tps/i3/T1BYd_XwFcXXb9RTPq-90-90.png" data-ks-lazyload="https://img.alicdn.com/imgextra/i1/1695308781/TB2hzoaak7OyuJjSspbXXXZuXXa_!!1695308781.jpg">
            </a>
           ...
            <img align="absmiddle" src="https://img-tmdetail.alicdn.com/tps/i3/T1BYd_XwFcXXb9RTPq.png" data-ks-lazyload="https://img.alicdn.com/imgextra/i1/1695308781/TB2KYjDwbplpuFjSspiXXcdfFXa_!!1695308781.jpg">
            <img align="absmiddle" src="https:////img-tmdetail.alicdn.com/tps/i3/T1BYd_XwFcXXb9RTPq.png" data-ks-lazyload="https://img.alicdn.com/imgextra/i1/1695308781/TB2VdBJcB0kpuFjSsziXXa.oVXa_!!1695308781.jpg" style="line-height: 1.5;">
            <img align="absmiddle" src="//img-tmdetail.alicdn.com/tps/i3/T1BYd_XwFcXXb9RTPq-90-90.png" data-ks-lazyload="https://img.alicdn.com/imgextra/i4/1695308781/TB2LSeGdSVmpuFjSZFFXXcZApXa_!!1695308781.jpg" style="line-height: 1.5;">
            ...
            </a>
        </p>
        </div>
  </div>

Rất mong anh chỉ điểm thêm vấn đề này nữa ạ! Cảm ơn anh nhiều!

0
| Reply
Share
Aug 28th, 2017 8:43 AM

@qaqeqe0 Bạn muốn lấy gì từ trang đó. Bạn chỉ cần return giá trị đó trong hàm page.evaluate là OK :slight_smile:

images = await page.evaluate(() => {
	return Array.from(document.querySelectorAll('[data-ks-lazyload]'))
		.map(ele => ele.dataset.ksLazyload)
})
0
| Reply
Share
Tu Nguyen @qaqeqe0
Aug 28th, 2017 4:11 PM

ok anh! Thanks anh nhiều nhé!

0
| Reply
Share
Sep 20th, 2017 10:30 AM

cho mình hỏi ngu cái nha. cái này áp dụng cho website php . mà soucre web nằm trên server thì có thể dùng được không bạn.

0
| Reply
Share
Nguyen Lan @zhuylanz
Jan 14th, 2018 9:52 AM

anh Khánh cho em hỏi hàm evaluate() là để làm gì vậy ạ? Để hiểu các khái niệm này mình nên tìm đọc tài liệu nào ạ?

0
| Reply
Share
Jan 14th, 2018 11:56 AM

@zhuylanz Có 2 môi trường ở đây. 1 là môi trường chạy script này. 2 là môi trường ở trang mình muốn lấy dữ liệu. Hàm evaluate để trả dữ liệu từ môi trường 2 về môi trường 1 để mình xử lý đó bạn 😄

0
| Reply
Share
Nguyễn Văn Huy @nguyenhuy98
May 30th, 2018 10:22 AM

Anh cho em hỏi là làm sau khi lấy thông tin của website rồi, nhưng chỉ console được ở cmd thôi, làm thế nào để hiển thị dữ liệu đó lên server mình tạo bằng node js ạ

0
| Reply
Share
May 30th, 2018 10:29 AM

@nguyenhuy98 Thay vì việc bạn chạy node index.js từ shell thì bạn phải khởi tạo một http server rồi nhúng đoạn code đó trong một cái route trên server là được. Cách tạo server bạn tham khảo https://nodejs.org/api/http.html nhé

0
| Reply
Share