Cách tốt nhất để thu thập dữ liệu từ một trang web là gì? [đóng cửa]


107

Tôi cần trích xuất nội dung từ một trang web nhưng ứng dụng không cung cấp bất kỳ giao diện lập trình ứng dụng nào hoặc một cơ chế nào khác để truy cập dữ liệu đó theo chương trình.

Tôi đã tìm thấy một công cụ hữu ích của bên thứ ba có tên là Import.io cung cấp chức năng nhấp và truy cập để quét các trang web và xây dựng tập dữ liệu, điều duy nhất là tôi muốn giữ dữ liệu của mình cục bộ và tôi không muốn đăng ký bất kỳ gói đăng ký nào .

Loại kỹ thuật nào mà công ty này sử dụng để quét các trang web và xây dựng bộ dữ liệu của họ? Tôi đã tìm thấy một số khuôn khổ tìm kiếm web pjscrape & Scrapy, chúng có thể cung cấp một tính năng như vậy không


4
PHP chắc chắn không nằm ngoài câu hỏi, điều đó rõ ràng là sai. gist.github.com/krakjoe/b1526fcc828621e840cb
Joe Watkins

@JoeWatkins trông thật tuyệt, nó có cần cấu hình PHP đặc biệt để chạy không? Và hiệu suất như thế nào so với các công cụ / ngôn ngữ được cung cấp bên dưới?
0x1ad2

1
Nó yêu cầu một bản xây dựng an toàn chuỗi của PHP và pthreads, hãy đọc github.com/krakjoe/pthreads/blob/master/README.md , bạn có thể tìm thấy tôi trong cuộc trò chuyện nếu bạn muốn giúp đỡ, tôi hoặc bất kỳ ai khác :)
Joe Watkins

@ 0x1ad2 Nếu bạn muốn giữ dữ liệu cục bộ thì bạn nên thử phần mềm ( datascraping.co ) thay vì Web API. Hầu hết các công cụ sử dụng Xpath, CSS selector và REGEX để trích xuất dữ liệu từ các trang web và Data Scraping Studio hỗ trợ cả 3 tính năng này.
Vikash Rathee

Có hai cách, một là triển khai của riêng bạn bằng cách sử dụng các thư viện mã nguồn mở / miễn phí, việc này tốn rất nhiều công sức. Theo nghĩa đen, bạn có thể tạo trình thu thập thông tin web ajax cho bất kỳ trang web nào bằng cách sử dụng scrape.it Đây là một công cụ trả phí nhưng nó hoạt động khi cả các công cụ miễn phí như import.io hay kimono đều không thể hiển thị.
Tôi yêu Python

Câu trả lời:


271

Bạn chắc chắn sẽ muốn bắt đầu với một khuôn khổ quét web tốt. Sau này, bạn có thể quyết định rằng chúng quá giới hạn và bạn có thể tập hợp chồng thư viện của riêng mình nhưng nếu không có nhiều kinh nghiệm thì thiết kế của bạn sẽ kém hơn nhiều so với pjscrape hoặc scrapy.

Lưu ý: Tôi sử dụng các thuật ngữ thu thập dữ liệu và cạo về cơ bản có thể hoán đổi cho nhau ở đây. Đây là bản sao câu trả lời của tôi cho câu hỏi Quora của bạn, nó khá dài.

Công cụ

Làm quen với các công cụ dành cho nhà phát triển Firebug hoặc Chrome tùy thuộc vào trình duyệt ưa thích của bạn. Điều này sẽ hoàn toàn cần thiết khi bạn duyệt trang web mà bạn đang lấy dữ liệu từ đó và vạch ra những url nào chứa dữ liệu bạn đang tìm kiếm và những định dạng dữ liệu nào tạo nên phản hồi.

Bạn sẽ cần có kiến ​​thức làm việc tốt về HTTP cũng như HTML và có thể sẽ muốn tìm một người đàn ông tốt trong phần mềm proxy trung gian. Bạn sẽ cần phải có khả năng kiểm tra các yêu cầu và phản hồi HTTP cũng như hiểu cách các cookie và thông tin phiên cũng như các tham số truy vấn đang được chuyển xung quanh. Fiddler ( http://www.telerik.com/fiddler ) và Charles Proxy ( http://www.charlesproxy.com/ ) là những công cụ phổ biến. Tôi sử dụng mitmproxy ( http://mitmproxy.org/ ) rất nhiều vì tôi là một anh chàng bàn phím hơn là một anh chàng chuột.

Một số loại môi trường kiểu console / shell / REPL nơi bạn có thể thử nhiều đoạn mã khác nhau với phản hồi tức thì sẽ là vô giá. Các tác vụ thiết kế ngược như thế này có rất nhiều thử nghiệm và sai sót, vì vậy bạn sẽ muốn có một quy trình làm việc dễ dàng.

Ngôn ngữ

Về cơ bản, PHP không phù hợp với công việc này và hỗ trợ thư viện / khung công tác kém trong lĩnh vực này. Python (Scrapy là một điểm khởi đầu tuyệt vời) và Clojure / Clojurescript (cực kỳ mạnh mẽ và hiệu quả nhưng là một đường cong học tập lớn) là những ngôn ngữ tuyệt vời cho vấn đề này. Vì bạn không muốn học một ngôn ngữ mới và bạn đã biết Javascript, tôi chắc chắn khuyên bạn nên gắn bó với JS. Tôi chưa sử dụng pjscrape nhưng nó trông khá tốt khi đọc nhanh tài liệu của họ. Nó rất phù hợp và thực hiện một giải pháp tuyệt vời cho vấn đề mà tôi mô tả bên dưới.

Lưu ý về Biểu thức chính quy: KHÔNG SỬ DỤNG CÁC BIỂU HIỆN THƯỜNG XUYÊN ĐỂ PHỤC HỒI HTML. Rất nhiều người mới bắt đầu làm điều này vì họ đã quen với regexes. Đó là một sai lầm lớn, sử dụng bộ chọn xpath hoặc css để điều hướng html và chỉ sử dụng biểu thức chính quy để trích xuất dữ liệu từ văn bản thực bên trong nút html. Điều này có thể đã quá rõ ràng đối với bạn, nó sẽ trở nên rõ ràng nhanh chóng nếu bạn thử nó nhưng rất nhiều người đã lãng phí rất nhiều thời gian để đi xuống con đường này vì một số lý do. Đừng sợ các bộ chọn xpath hoặc css, chúng dễ học hơn regexes và chúng được thiết kế để giải quyết vấn đề chính xác này.

Các trang web nặng về Javascript

Ngày xưa, bạn chỉ cần thực hiện một yêu cầu http và phân tích cú pháp HTML reponse. Bây giờ bạn gần như chắc chắn sẽ phải đối phó với các trang web là sự kết hợp của các yêu cầu / phản hồi HTTP chuẩn HTML và các lệnh gọi HTTP không đồng bộ được thực hiện bởi phần javascript của trang web đích. Đây là nơi phần mềm proxy của bạn và tab mạng của firebug / devtools rất hữu ích. Các phản hồi cho những thứ này có thể là html hoặc chúng có thể là json, trong một số trường hợp hiếm hoi, chúng sẽ là xml hoặc một cái gì đó khác.

Có hai cách tiếp cận vấn đề này:

Cách tiếp cận cấp thấp:

Bạn có thể tìm ra url ajax mà trang web javascript đang gọi và những phản hồi đó trông như thế nào và tự đưa ra những yêu cầu tương tự. Vì vậy, bạn có thể kéo html từ http://example.com/foobar và trích xuất một phần dữ liệu và sau đó phải kéo phản hồi json từ http://example.com/api/baz?foo=b ... sang lấy phần dữ liệu khác. Bạn sẽ cần lưu ý về việc chuyển đúng cookie hoặc thông số phiên. Nó rất hiếm, nhưng đôi khi một số tham số bắt buộc cho một lệnh gọi ajax sẽ là kết quả của một số tính toán điên rồ được thực hiện trong javascript của trang web, điều này có thể gây khó chịu.

Phương pháp tiếp cận trình duyệt nhúng:

Tại sao bạn cần phải tìm ra dữ liệu trong html và dữ liệu nào đến từ lệnh gọi ajax? Quản lý tất cả dữ liệu phiên và cookie đó? Bạn không cần phải làm như vậy khi duyệt một trang web, trình duyệt và javascript của trang web sẽ làm điều đó. Đó là toàn bộ vấn đề.

Nếu bạn chỉ tải trang vào một công cụ trình duyệt không đầu như phantomjs, nó sẽ tải trang, chạy javascript và cho bạn biết khi nào tất cả các lệnh gọi ajax đã hoàn thành. Bạn có thể chèn javascript của riêng mình nếu cần để kích hoạt các nhấp chuột thích hợp hoặc bất kỳ thứ gì cần thiết để kích hoạt javascript trang web tải dữ liệu thích hợp.

Bây giờ bạn có hai tùy chọn, lấy nó để lấy ra html đã hoàn thành và phân tích cú pháp nó hoặc đưa một số javascript vào trang phân tích cú pháp và định dạng dữ liệu của bạn và chia dữ liệu ra (có thể ở định dạng json). Bạn có thể tự do kết hợp hai tùy chọn này.

Cách tiếp cận nào là tốt nhất?

Điều đó phụ thuộc, bạn chắc chắn sẽ cần phải làm quen và thoải mái với cách tiếp cận cấp độ thấp. Phương pháp tiếp cận trình duyệt nhúng hoạt động cho mọi thứ, nó sẽ dễ thực hiện hơn nhiều và sẽ làm biến mất một số vấn đề phức tạp nhất trong việc cạo. Nó cũng là một bộ phận máy móc khá phức tạp mà bạn cần phải hiểu. Nó không chỉ là các yêu cầu và phản hồi HTTP, đó là các yêu cầu, kết xuất trình duyệt được nhúng, javascript trang web, javascript được chèn, mã của riêng bạn và tương tác 2 chiều với quy trình trình duyệt được nhúng.

Trình duyệt nhúng cũng chậm hơn nhiều ở quy mô do chi phí hiển thị nhưng điều đó gần như chắc chắn sẽ không thành vấn đề trừ khi bạn đang tìm kiếm nhiều tên miền khác nhau. Việc bạn phải xếp hạng giới hạn yêu cầu của bạn sẽ làm cho thời gian hiển thị hoàn toàn không đáng kể trong trường hợp của một tên miền.

Giới hạn tỷ lệ / hành vi bot

Bạn cần hết sức lưu ý điều này. Bạn cần thực hiện các yêu cầu đối với các tên miền mục tiêu của mình với tốc độ hợp lý. Bạn cần phải viết một bot hoạt động tốt khi thu thập dữ liệu các trang web và điều đó có nghĩa là tôn trọng robots.txt và không đập máy chủ với các yêu cầu. Sai lầm hoặc sơ suất ở đây là rất phi đạo đức vì đây có thể được coi là một cuộc tấn công từ chối dịch vụ. Tỷ lệ chấp nhận được thay đổi tùy thuộc vào người bạn yêu cầu, 1req / s là tối đa mà trình thu thập thông tin của Google chạy nhưng bạn không phải là Google và bạn có thể không được chào đón như Google. Giữ nó càng chậm càng tốt. Tôi sẽ đề xuất 2-5 giây giữa mỗi yêu cầu trang.

Xác định các yêu cầu của bạn bằng chuỗi tác nhân người dùng xác định bot của bạn và có một trang web cho bot của bạn giải thích mục đích của nó. Url này nằm trong chuỗi đại lý.

Bạn sẽ rất dễ bị chặn nếu trang web muốn chặn bạn. Một kỹ sư thông minh ở phía cuối của họ có thể dễ dàng xác định các bot và một vài phút làm việc của họ có thể khiến bạn phải mất hàng tuần làm việc để thay đổi mã cạo của bạn hoặc khiến nó không thể thực hiện được. Nếu mối quan hệ là đối kháng thì một kỹ sư thông minh tại địa điểm mục tiêu hoàn toàn có thể cản trở một kỹ sư thiên tài viết trình thu thập thông tin. Scraping code vốn rất mỏng manh và điều này rất dễ bị lợi dụng. Dù sao thì điều gì đó có thể kích động phản ứng này gần như chắc chắn là phi đạo đức, vì vậy hãy viết một bot hoạt động tốt và đừng lo lắng về điều này.

Thử nghiệm

Không phải là người kiểm tra đơn vị / tích hợp? Quá tệ. Bây giờ bạn sẽ phải trở thành một. Các trang web thường xuyên thay đổi và bạn sẽ thường xuyên thay đổi mã của mình. Đây là một phần lớn thách thức.

Có rất nhiều bộ phận chuyển động tham gia vào việc cạo một trang web hiện đại, thực hành kiểm tra tốt sẽ giúp ích rất nhiều. Nhiều lỗi bạn sẽ gặp phải khi viết loại mã này sẽ là loại chỉ trả về dữ liệu bị hỏng một cách âm thầm. Nếu không có các bài kiểm tra tốt để kiểm tra các hồi quy, bạn sẽ phát hiện ra rằng bạn đã lưu dữ liệu bị hỏng vô ích vào cơ sở dữ liệu của mình trong một thời gian mà không nhận thấy. Dự án này sẽ giúp bạn rất quen thuộc với việc xác thực dữ liệu (tìm một số thư viện tốt để sử dụng) và thử nghiệm. Không có nhiều vấn đề khác kết hợp yêu cầu kiểm tra toàn diện và rất khó kiểm tra.

Phần thứ hai của các bài kiểm tra của bạn liên quan đến bộ nhớ đệm và phát hiện thay đổi. Trong khi viết mã, bạn không muốn đóng máy chủ cho cùng một trang lặp đi lặp lại mà không có lý do. Trong khi chạy các bài kiểm tra đơn vị, bạn muốn biết liệu các bài kiểm tra của mình có thất bại hay không vì bạn đã phá vỡ mã của mình hay vì trang web đã được thiết kế lại. Chạy các bài kiểm tra đơn vị của bạn dựa trên bản sao lưu trong bộ nhớ cache của các url liên quan. Một proxy bộ nhớ đệm rất hữu ích ở đây nhưng khó cấu hình và sử dụng đúng cách.

Bạn cũng muốn biết nếu trang web đã thay đổi. Nếu họ thiết kế lại trang web và trình thu thập thông tin của bạn bị hỏng, các bài kiểm tra đơn vị của bạn sẽ vẫn vượt qua vì chúng đang chạy với một bản sao được lưu trong bộ nhớ cache! Bạn sẽ cần một bộ kiểm tra tích hợp khác, nhỏ hơn được chạy không thường xuyên trên trang web đang hoạt động hoặc ghi nhật ký tốt và phát hiện lỗi trong mã thu thập thông tin của bạn để ghi lại các vấn đề chính xác, cảnh báo cho bạn về sự cố và ngừng thu thập thông tin. Giờ đây, bạn có thể cập nhật bộ nhớ cache, chạy các bài kiểm tra đơn vị và xem bạn cần thay đổi những gì.

Vấn đề pháp lý

Luật pháp ở đây có thể hơi nguy hiểm nếu bạn làm những điều ngu ngốc. Nếu luật có liên quan, bạn đang phải đối phó với những người thường xuyên coi wget và curl là "công cụ hack". Bạn không muốn điều này.

Thực tế đạo đức của tình huống là không có sự khác biệt giữa việc sử dụng phần mềm trình duyệt để yêu cầu url và xem một số dữ liệu và sử dụng phần mềm của riêng bạn để yêu cầu url và xem một số dữ liệu. Google là công ty cạo râu lớn nhất trên thế giới và họ được yêu thích vì điều đó. Việc xác định tên bot của bạn trong tác nhân người dùng và cởi mở về các mục tiêu và ý định của trình thu thập thông tin web của bạn sẽ giúp ích ở đây vì luật pháp hiểu Google là gì. Nếu bạn đang làm bất cứ điều gì mờ ám, chẳng hạn như tạo tài khoản người dùng giả mạo hoặc truy cập vào các khu vực của trang web mà bạn không nên (bị robots.txt "chặn" hoặc do một số loại khai thác ủy quyền) thì hãy lưu ý rằng bạn đang làm điều gì đó phi đạo đức và sự thiếu hiểu biết của pháp luật về công nghệ sẽ cực kỳ nguy hiểm ở đây. Đó là một tình huống nực cười nhưng đó là một tình huống có thật.

Theo đúng nghĩa đen, bạn hoàn toàn có thể thử và xây dựng một công cụ tìm kiếm mới với tư cách là một công dân xuất sắc, mắc lỗi hoặc có lỗi trong phần mềm của bạn và bị coi là tin tặc. Không phải là điều bạn muốn nếu xét đến thực tế chính trị hiện tại.

Tôi là ai để viết bức tường văn bản khổng lồ này?

Tôi đã viết rất nhiều mã liên quan đến thu thập dữ liệu web trong cuộc đời mình. Tôi đã làm công việc phát triển phần mềm liên quan đến web trong hơn một thập kỷ với tư cách là nhà tư vấn, nhân viên và người sáng lập công ty khởi nghiệp. Những ngày đầu viết trình thu thập thông tin / công cụ quét perl và các trang web php. Khi chúng tôi nhúng các iframe ẩn tải dữ liệu csv vào các trang web để thực hiện ajax trước khi Jesse James Garrett đặt tên nó là ajax, trước khi XMLHTTPRequest là một ý tưởng. Trước jQuery, trước json. Tôi đã ngoài 30 tuổi, điều đó dường như được coi là cổ hủ đối với công việc kinh doanh này.

Tôi đã viết hệ thống thu thập dữ liệu / cạo quy mô lớn hai lần, một lần cho một nhóm lớn tại một công ty truyền thông (ở Perl) và gần đây cho một nhóm nhỏ với tư cách là CTO của một công ty khởi động công cụ tìm kiếm (bằng Python / Javascript). Tôi hiện đang làm tư vấn, chủ yếu viết mã trong Clojure / Clojurescript (một ngôn ngữ chuyên gia tuyệt vời nói chung và có các thư viện giúp các vấn đề về trình thu thập thông tin / trình quét trở nên thú vị)

Tôi cũng đã viết hệ thống phần mềm chống thu thập thông tin thành công. Thật dễ dàng để viết các trang web không thể đóng gói nếu bạn muốn hoặc để xác định và phá hoại các bot mà bạn không thích.

Tôi thích viết trình thu thập thông tin, trình thu thập dữ liệu và trình phân tích cú pháp hơn bất kỳ loại phần mềm nào khác. Nó đầy thử thách, thú vị và có thể được sử dụng để tạo ra những điều tuyệt vời.


4
Tôi đã từng đồng ý với bạn về việc PHP là một lựa chọn tồi, nhưng với các thư viện phù hợp thì nó không quá tệ. Thao tác Regex và mảng / sting là vụng về nhưng mặt tích cực là nó nhanh và ở mọi nơi.
pguardiario

3
Trong một môi trường mà có một vài thư viện khiến việc này trở nên thú vị và rất nhiều thư viện làm cho nó khá đơn giản và khá dễ dàng ... tại sao bạn lại giải quyết cho "không quá tệ". Tôi đồng ý, nó có thể làm được trong PHP (và FORTRAN, C, VB, v.v.) nhưng trừ khi vấn đề của bạn thực sự đơn giản thì tốt hơn là sử dụng các công cụ phù hợp cho công việc. Và một lần nữa, trừ khi bạn có một vấn đề cực kỳ đơn giản cần giải quyết ... thì vấn đề gì mà regex ở khắp mọi nơi? Việc cài đặt các thư viện đơn giản hơn nhiều so với hầu hết mọi vấn đề. Và trên thực tế, regex thường khá chậm cho vấn đề này.
Jesse Sherlock

5
Bạn có thể đúng, nhưng tôi biết thực tế là tôi không thể làm điều đó dễ dàng trong PHP. Trước khi rời khỏi PHP, tôi đã có gần một thập kỷ kinh nghiệm về PHP chuyên nghiệp. Tôi đã dành hơn một năm toàn thời gian để xây dựng một hệ thống cóp nhặt trên quy mô lớn, bằng Python và tôi không thể tưởng tượng được việc làm mà không có một số thư viện đẹp không có sẵn trong PHP hoặc làm mà không có các kỹ thuật lập trình siêu ngắn gọn có sẵn trong Python . Đó cũng là lý do tôi chuyển đến Clojure, để có được khả năng lập trình meta mạnh mẽ hơn nữa.
Jesse Sherlock

4
Enlive, cùng với sức mạnh của chính Clojure cho mã cụ thể của dự án, là những người chiến thắng lớn nhất. Schema là một thư viện xác thực tuyệt vời, là một phần lớn của mã trích xuất thông tin. Tôi hiện thực sự hài lòng với khả năng tương tác dễ dàng với thế giới Java cho những thứ như Mahout cũng như Nashorn / Rhino cho một số loại thực thi js. Và những người sử dụng Clojure là những người viết lib như thế này github.com/shriphani/subotai để bạn không phải làm vậy. ... tiếp tục trong bình luận tiếp theo ...
Jesse Sherlock

3
Tôi cũng nhận thấy rằng khi bạn thực sự cần một trình duyệt thực sự và cần sử dụng phantomjs / casperjs thì việc sử dụng clojurescript (thường là mã được chia sẻ giữa clj và cljs bằng cljx) để viết js bạn đưa vào trang thay vì clojurescript thì thực sự tuyệt vời. . Core.async rất tuyệt vời để điều phối mã thu thập thông tin đồng thời cao trên máy chủ cũng như thoát khỏi địa ngục gọi lại bên trong môi trường js (phối hợp tự động hóa trình duyệt với mã cljs core.async bên trong phantomjs là thiên đường so với các lựa chọn thay thế).
Jesse Sherlock

21

Có bạn có thể làm điều đó cho mình. Nó chỉ là vấn đề lấy các nguồn của trang và phân tích chúng theo cách bạn muốn.

Có nhiều khả năng khác nhau. Một kết hợp tốt là sử dụng python-request (được xây dựng trên urllib2, nó nằm urllib.requesttrong Python3) và BeautifulSoup4 , có các phương pháp để chọn các phần tử và cũng cho phép các bộ chọn CSS :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Một số sẽ thích phân tích cú pháp xpath hoặc pyquery giống jquery, lxml hoặc thứ gì đó khác .

Khi dữ liệu bạn muốn được tạo ra bởi một số JavaScript , những điều trên sẽ không hoạt động. Bạn cần python-ghost hoặc Selenium. Tôi thích cái sau được kết hợp với PhantomJS , nhẹ hơn và cài đặt đơn giản hơn nhiều và dễ sử dụng:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Tôi muốn lời khuyên để bắt đầu giải pháp của riêng bạn. Bạn sẽ hiểu lợi ích của Scrapy khi làm như vậy.

ps: hãy xem qua một chút: https://github.com/scrapy/scrapely

pps: hãy xem Portia, để bắt đầu trích xuất thông tin một cách trực quan mà không cần kiến ​​thức lập trình: https://github.com/scrapinghub/portia


Được rồi, cảm ơn người thử nghiệm, vấn đề duy nhất là Python không có trong bộ kỹ năng của tôi. Có ngôn ngữ lập trình tốt nào khác có thể thực hiện các nhiệm vụ tương tự không? Tôi chủ yếu làm việc với PHP và Javascript.
0x1ad2

Xin lỗi vì sự nhầm lẫn (tôi đã đề cập đến khung Python trong câu hỏi của mình), nhưng nếu Python là cách tốt nhất để làm điều đó, tôi có thể học nó.
0x1ad2

Python làm phế liệu rất dễ dàng. Nó cũng dễ học. Máy cạo tốt nhất hoạt động tốt tại thời điểm hiện tại là máy nạo. Họ cũng có một tài liệu rất tốt.
Abhishek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.