2013-05-28 62 views
7

Tôi muốn xóa dữ liệu từ một trang web có TextFields, Buttons v.v .. và yêu cầu của tôi là điền vào các trường văn bản và gửi biểu mẫu để nhận kết quả và sau đó cạo các điểm dữ liệu từ trang kết quả .Quét dữ liệu Python bằng Scrapy

Tôi muốn biết rằng không có tính năng này hoặc nếu có ai có thể đề xuất một thư viện bằng Python để thực hiện tác vụ này?

(chỉnh sửa)
Tôi muốn cạo dữ liệu từ các trang web sau đây:
http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentType

Yêu cầu của tôi là để chọn các giá trị từ ComboBoxes và nhấn nút tìm kiếm và cạo các điểm dữ liệu từ kết quả trang.

P.S. Tôi đang sử dụng trình điều khiển Firefox selenium để loại bỏ dữ liệu từ một số trang web khác nhưng giải pháp đó không tốt vì trình điều khiển Firefox selenium phụ thuộc vào EXE của FireFox nghĩa là Firefox phải được cài đặt trước khi chạy scraper.

Trình điều khiển Selenium Firefox tiêu thụ bộ nhớ khoảng 100MB cho một trường hợp và yêu cầu của tôi là chạy nhiều lần cùng một lúc để quá trình cạo nhanh chóng cũng có giới hạn về bộ nhớ.

Đôi khi Firefox gặp sự cố trong khi thực hiện scraper, không biết tại sao. Ngoài ra tôi cần cửa sổ ít cạo mà không phải là có thể trong trường hợp của trình điều khiển Selenium Firefox.

Mục tiêu cuối cùng của tôi là chạy các trình gỡ rối trên Heroku và tôi có môi trường Linux ở đó vì vậy trình điều khiển Firefox selenium sẽ không hoạt động trên Heroku. Cảm ơn

Trả lời

15

Về cơ bản, bạn có rất nhiều công cụ để lựa chọn:

Những công cụ này có mục đích khác nhau nhưng chúng có thể được pha trộn với nhau tùy thuộc vào nhiệm vụ.

Phế liệu là một công cụ mạnh mẽ và rất thông minh để thu thập dữ liệu trang web, trích xuất dữ liệu. Tuy nhiên, khi nói đến việc thao tác trang: nhấn nút, điền hình thức - nó trở nên phức tạp hơn:

  • đôi khi, thật dễ dàng để mô phỏng điền/nộp tờ bằng cách làm cho hình thức hành động cơ bản trực tiếp trong scrapy
  • đôi khi, bạn phải sử dụng các công cụ khác để trợ giúp - giống như cơ giới hóa hoặc selenium

Nếu bạn đặt câu hỏi cụ thể hơn, nó sẽ giúp bạn hiểu loại công cụ bạn nên sử dụng hoặc lựa chọn.

Hãy xem ví dụ về sự kết hợp selenium đầy bụi bẩn thú vị &. Ở đây, nhiệm vụ selen là nhấp vào nút và cung cấp dữ liệu cho các hạng mục scrapy:

import time 
from scrapy.item import Item, Field 

from selenium import webdriver 

from scrapy.spider import BaseSpider 


class ElyseAvenueItem(Item): 
    name = Field() 


class ElyseAvenueSpider(BaseSpider): 
    name = "elyse" 
    allowed_domains = ["ehealthinsurance.com"] 
    start_urls = [ 
    'http://www.ehealthinsurance.com/individual-family-health-insurance?action=changeCensus&census.zipCode=48341&census.primary.gender=MALE&census.requestEffectiveDate=06/01/2013&census.primary.month=12&census.primary.day=01&census.primary.year=1971'] 

    def __init__(self): 
     self.driver = webdriver.Firefox() 

    def parse(self, response): 
     self.driver.get(response.url) 
     el = self.driver.find_element_by_xpath("//input[contains(@class,'btn go-btn')]") 
     if el: 
      el.click() 

     time.sleep(10) 

     plans = self.driver.find_elements_by_class_name("plan-info") 
     for plan in plans: 
      item = ElyseAvenueItem() 
      item['name'] = plan.find_element_by_class_name('primary').text 
      yield item 

     self.driver.close() 

UPDATE:

Dưới đây là một ví dụ về cách sử dụng scrapy trong trường hợp của bạn:

from scrapy.http import FormRequest 
from scrapy.item import Item, Field 
from scrapy.selector import HtmlXPathSelector 

from scrapy.spider import BaseSpider 


class AcrisItem(Item): 
    borough = Field() 
    block = Field() 
    doc_type_name = Field() 


class AcrisSpider(BaseSpider): 
    name = "acris" 
    allowed_domains = ["a836-acris.nyc.gov"] 
    start_urls = ['http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentType'] 


    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     document_classes = hxs.select('//select[@name="combox_doc_doctype"]/option') 

     form_token = hxs.select('//input[@name="__RequestVerificationToken"]/@value').extract()[0] 
     for document_class in document_classes: 
      if document_class: 
       doc_type = document_class.select('.//@value').extract()[0] 
       doc_type_name = document_class.select('.//text()').extract()[0] 
       formdata = {'__RequestVerificationToken': form_token, 
          'hid_selectdate': '7', 
          'hid_doctype': doc_type, 
          'hid_doctype_name': doc_type_name, 
          'hid_max_rows': '10', 
          'hid_ISIntranet': 'N', 
          'hid_SearchType': 'DOCTYPE', 
          'hid_page': '1', 
          'hid_borough': '0', 
          'hid_borough_name': 'ALL BOROUGHS', 
          'hid_ReqID': '', 
          'hid_sort': '', 
          'hid_datefromm': '', 
          'hid_datefromd': '', 
          'hid_datefromy': '', 
          'hid_datetom': '', 
          'hid_datetod': '', 
          'hid_datetoy': '', } 
       yield FormRequest(url="http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentTypeResult", 
            method="POST", 
            formdata=formdata, 
            callback=self.parse_page, 
            meta={'doc_type_name': doc_type_name}) 

    def parse_page(self, response): 
     hxs = HtmlXPathSelector(response) 

     rows = hxs.select('//form[@name="DATA"]/table/tbody/tr[2]/td/table/tr') 
     for row in rows: 
      item = AcrisItem() 
      borough = row.select('.//td[2]/div/font/text()').extract() 
      block = row.select('.//td[3]/div/font/text()').extract() 

      if borough and block: 
       item['borough'] = borough[0] 
       item['block'] = block[0] 
       item['doc_type_name'] = response.meta['doc_type_name'] 

       yield item 

Lưu nó trong spider.py và chạy qua scrapy runspider spider.py -o output.json và trong output.json bạn sẽ thấy:

{"doc_type_name": "CONDEMNATION PROCEEDINGS ", "borough": "Borough", "block": "Block"} 
{"doc_type_name": "CERTIFICATE OF REDUCTION ", "borough": "Borough", "block": "Block"} 
{"doc_type_name": "COLLATERAL MORTGAGE ", "borough": "Borough", "block": "Block"} 
{"doc_type_name": "CERTIFIED COPY OF WILL ", "borough": "Borough", "block": "Block"} 
{"doc_type_name": "CONFIRMATORY DEED ", "borough": "Borough", "block": "Block"} 
{"doc_type_name": "CERT NONATTCHMENT FED TAX LIEN ", "borough": "Borough", "block": "Block"} 
... 

Hy vọng rằng sẽ giúp.

+0

Trình điều khiển Selenium Firefox tiêu thụ khoảng 100MB bộ nhớ cho một trường hợp và yêu cầu của tôi là chạy nhiều lần cùng một lúc để làm cho quá trình cạo nhanh chóng để có giới hạn bộ nhớ. Đôi khi Firefox gặp sự cố trong khi thực hiện scraper, không biết tại sao. Ngoài ra tôi cần cửa sổ ít cạo mà không phải là có thể trong trường hợp của trình điều khiển Selenium Firefox. Mục tiêu cuối cùng của tôi là chạy các mẩu tin lưu niệm trên Heroku và tôi có môi trường Linux ở đó vì vậy trình điều khiển Firefox selenium sẽ không hoạt động trên Heroku. –

+0

Ok, trông giống như một biểu mẫu html đơn giản gửi yêu cầu đăng bài. Chỉ cần sử dụng phế liệu là đủ. Về lý thuyết, nó phải như thế này: cạo trang chính, nhận các lựa chọn từ các trường chọn, bắt đầu [Yêu cầu] (http://doc.scrapy.org/en/latest/topics/request-response.html # scrapy.http.Request) với một cuộc gọi lại - thu thập thông tin dữ liệu vào các mục cào trong cuộc gọi lại. Nếu bạn muốn, tôi có thể cung cấp một ví dụ. – alecxe

+0

Xin vui lòng, nó sẽ thực sự hữu ích cho tôi nếu bạn có thể đưa ra một ví dụ nhỏ về việc thực hiện. –

2

Cá nhân tôi sẽ sử dụng mechanize vì tôi không có bất kỳ trải nghiệm nào với sự cố. Tuy nhiên, một thư viện có tên là mục đích được xây dựng cho việc cạo màn hình nên được thực hiện. Tôi sẽ chỉ đi với cả hai người và xem công việc nào tốt nhất/dễ nhất.

3

Nếu bạn chỉ muốn gửi dữ liệu dạng và chiết xuất từ ​​các trang kết quả, tôi muốn đi cho:

  • requests để gửi yêu cầu bài
  • beautiful soup để trích xuất dữ liệu được lựa chọn từ các trang kết quả

Giá trị được thêm vào thực sự giữ khả năng theo dõi liên kết và thu thập dữ liệu trang web, tôi không nghĩ đó là công cụ phù hợp cho công việc nếu bạn biết chính xác những gì bạn đang tìm kiếm.

+1

Đó chỉ là ý kiến ​​của tôi, nhưng tôi cực kỳ thích lxml hơn B.S. Nhanh hơn đáng kể và có trình phân tích cú pháp dự phòng cho BS. Nếu bạn cố gắng sử dụng lxml trên html không đúng định dạng, chỉ cần nắm bắt ngoại lệ và đưa nó vào trình phân tích cú pháp xúp được xây dựng trong lxml. –

Các vấn đề liên quan