Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Tôi đang cố gắng đăng một số dữ liệu với yêu cầu POST AJAX và thực thi tệp Python, truy xuất dữ liệu trong tệp Python và trả về kết quả.

Tôi có mã Ajax sau

        $(function () {
                    $("#upload").on("click", function (e) {
                        $.ajax({
                            type: 'post',
                            url: "test1.py",
                            data: {'param1':'abc'},
                            async: false,
                            success: function (response) {
                                console.log(response);
                            }
                        }).done(function (data) {
                            console.log(data);
                        });
                    });
                });

Và tệp python sau

    #! /usr/bin/python
    from __future__ import print_function
    import cgi, cgitb
    def index():
        data = cgi.FieldStorage()
        mydata = data['param1'].value
        return return "test"

Tôi đang nhận được KeyError trên Param1 -> "KeyError: 'param1'". Tôi cũng đã cố gắng sử dụng getValue (dữ liệu ['param1']. Có vẻ như một vấn đề với việc chuyển dữ liệu từ cuộc gọi AJAX sang tệp Python mà tôi muốn thực thi ... nhưng tôi không thể tìm ra lý do tại sao.

Cảm ơn trước

Xuất bản ngày 19 tháng 12 năm 2016last cập nhật ngày 18 tháng 1 năm 2017

Quét web là một kỹ thuật được sử dụng để truy xuất thông tin từ một trang web bằng phần mềm. Có nhiều công cụ để thực hiện cào web với Python, một số trong số đó là:

  • Quét
  • Bầu trời
  • Súp đẹp
  • Yêu cầu

Vấn đề với hầu hết các công cụ này là chúng chỉ lấy HTML tĩnh xuất phát từ máy chủ chứ không phải phần động được hiển thị bằng JavaScript.

Họ là một số lựa chọn để khắc phục vấn đề này:

  1. Trình duyệt tự động

    Các trình duyệt web tự động như Selenium hoặc Splash là các trình duyệt đầy đủ chạy "không đầu". Thiết lập điều này là một chút phức tạp. Có những giải pháp ngoài kia để giảm thiểu điều này, chẳng hạn như Docker. Thiết lập những thứ này nằm ngoài phạm vi của tài liệu này, và vì vậy chúng tôi sẽ tập trung giải pháp của chúng tôi vào tùy chọn thứ hai bên dưới.
    Setting these up is beyond the scope of this document, and so we will focus our solution on the second option below.

  2. Đánh chặn các cuộc gọi Ajax

    Cố gắng chặn các cuộc gọi AJAX từ trang và sao chép/phát lại chúng.

Phạm vi của hướng dẫn này

Hướng dẫn này sẽ dạy bạn cách bắt các cuộc gọi Ajax và tái tạo chúng bằng thư viện requests và trình duyệt Google Chrome. Mặc dù các khung như

    #! /usr/bin/python
    from __future__ import print_function
    import cgi, cgitb
    def index():
        data = cgi.FieldStorage()
        mydata = data['param1'].value
        return return "test"
0 cung cấp một giải pháp mạnh mẽ hơn cho việc cạo web, nhưng không cần thiết cho tất cả các trường hợp. Các cuộc gọi AJAX hầu hết được thực hiện đối với API trả về một đối tượng JSON có thể dễ dàng xử lý bởi thư viện requests. Hướng dẫn này có thể được thực hiện với bất kỳ trình duyệt nào khác như Firefox - quá trình này là như nhau, điều duy nhất thay đổi là giao diện người dùng Dev Tools.

Đối với hướng dẫn này, chúng tôi sẽ sử dụng một ví dụ thực tế: Truy cập tất cả các địa điểm cửa hàng Wholefoods từ trang web của họ.

Hãy bắt đầu

Điều đầu tiên bạn cần biết là cố gắng tái tạo một cuộc gọi AJAX giống như sử dụng API không có giấy tờ, vì vậy bạn phải xem cuộc gọi mà các trang thực hiện. Truy cập trang web và chơi với nó, điều hướng qua một số trang và xem một số thông tin được hiển thị như thế nào mà không cần đến URL khác. Sau khi bạn chơi xong, hãy quay lại đây để bắt đầu cào.

Trước khi vào mã hóa, trước tiên chúng ta cần biết cách hoạt động của trang. Đối với điều đó, chúng tôi sẽ điều hướng qua các trang có chứa thông tin cửa hàng.

Đầu tiên, chúng ta hãy truy cập phần Lưu trữ của Trang web:

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Chúng ta hãy giới hạn việc quét của chúng tôi đối với các cửa hàng nằm ở Hoa Kỳ theo tiểu bang:

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Bây giờ chúng tôi thấy các cửa hàng của tiểu bang Hoa Kỳ. Chọn bất kỳ trạng thái nào và trang sẽ hiển thị thông tin của cửa hàng ở đó. Hãy thử nó ra và sau đó quay lại. Ngoài ra còn có tùy chọn để xem các cửa hàng theo trang, đây là tùy chọn mà chúng tôi sẽ sử dụng để loại bỏ trang.

Như bạn có thể thấy, mỗi khi bạn chọn một trạng thái hoặc trang, trang web hiển thị các cửa hàng mới, thay thế các cửa hàng cũ. Điều này được thực hiện bằng cách sử dụng cuộc gọi AJAX đến máy chủ yêu cầu các cửa hàng mới. Công việc của chúng tôi bây giờ là bắt được cuộc gọi đó và tái tạo nó. Vì vậy, hãy mở bảng điều khiển Chrome Devtools và chuyển đến phần mạng và tiểu mục XHR:

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

XHR (XMLHTTPREQUEST) là một giao diện để thực hiện các yêu cầu HTTP và HTTPS, vì vậy rất có thể yêu cầu AJAX sẽ được hiển thị ở đây.

Bây giờ, trong khi giám sát mạng, chọn trang thứ hai để xem điều gì sẽ xảy ra. Bạn sẽ thấy một cái gì đó như thế này:

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Nếu bạn nhấp đúp vào cuộc gọi AJAX, bạn sẽ thấy rằng có rất nhiều thông tin về các cửa hàng. Bạn cũng có thể xem trước các yêu cầu. Hãy làm điều đó để xem nếu thông tin mà chúng tôi muốn có ở đó không. Cuộc gọi AJAX không phải lúc nào cũng có tên "Ajax", nó có thể có bất kỳ tên nào, vì vậy bạn phải xem dữ liệu nào đến trong mỗi cuộc gọi của tiểu mục XHR.

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Một phản hồi đến ở định dạng JSON. Nó có 3 yếu tố và thông tin mà chúng tôi muốn là trong phần cuối cùng. Phần tử này chứa một khóa dữ liệu có HTML được chèn vào trang khi một trang được chọn. Như bạn sẽ lưu ý, HTML nằm trong một dòng văn bản thực sự dài. Bạn có thể sử dụng một cái gì đó như Code Beautify để "thanh toán" nó. Khối mã tương ứng với mọi cửa hàng đều có trong ý chính này. Trong khối này là tất cả những gì chúng ta cần.

Bây giờ chúng tôi xem phần tiêu đề để xem tất cả các thông tin đi đến máy chủ trong cuộc gọi.

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Ở đây chúng tôi thấy URL yêu cầu và phương thức yêu cầu là đăng. Bây giờ hãy xem dữ liệu biểu mẫu được gửi đến máy chủ.

Hướng dẫn how to get data from ajax request in python - cách lấy dữ liệu từ yêu cầu ajax trong python

Như bạn có thể thấy, rất nhiều dữ liệu được gửi đến máy chủ, nhưng đừng lo lắng - không cần thiết. Để xem dữ liệu nào thực sự cần thiết, bạn có thể mở bảng điều khiển và thực hiện các yêu cầu đăng khác nhau cho URL yêu cầu bằng thư viện yêu cầu, tôi đã làm điều đó cho chúng tôi và nhấn mạnh dữ liệu cần thiết.

Viết cạp trang web của riêng bạn

Bây giờ chúng tôi đã biết cách thức hoạt động và giải mã cuộc gọi AJAX, đã đến lúc bắt đầu viết cào của chúng tôi. Tất cả các mã được viết ở đây đều có sẵn trong kho GitHub này.

Chúng tôi sẽ sử dụng bộ chọn LXML CSS để trích xuất thông tin mà chúng tôi cần. Chúng tôi sẽ trích xuất như sau:

  • Tên cửa hàng
  • Địa chỉ đầy đủ
  • Số điện thoại
  • Giờ mở cửa

Trước tiên hãy tạo một dự án và CD cho nó.

$ mrkdir wholefoods-scraper
$ cd wholefoods-scraper

Chúng ta nên tạo ra một ảo.

$ virtualenv venv
$ source venv/bin/activate

Bây giờ chúng tôi có thể cài đặt thư viện yêu cầu và tạo tệp python cho cạp.

$ pip install requests
$ pip install lxml
$ pip install cssselect
$ touch scraper.py

Bây giờ hãy mở tệp Python với trình soạn thảo yêu thích của bạn. Hãy bắt đầu tạo cào của chúng tôi với một lớp và tạo một chức năng để thực hiện sao chép cuộc gọi AJAX:

# Importing the dependencies
# This is needed to create a lxml object that uses the css selector
 from lxml.etree import fromstring
  
# The requests library
import requests
  
class WholeFoodsScraper:
  
  API_url = 'http://www.wholefoodsmarket.com/views/ajax'
    scraped_stores = []

    def get_stores_info(self, page):
     
        # This is the only data required by the api 
        # To send back the stores info
        data = {
        'view_name': 'store_locations_by_state',
        'view_display_id': 'state',
        'page': page
        }
        # Making the post request
        response = requests.post(self.API_url, data=data)

        # The data that we are looking is in the second
        # Element of the response and has the key 'data', 
        # so that is what's returned
        return response.json()[1]['data']

Bây giờ chúng tôi có một chức năng lấy dữ liệu từ các cửa hàng, hãy tạo một chức năng để phân tích dữ liệu đó bằng bộ chọn CSS, hãy nhìn vào ý chính nếu bạn bị lạc.

import ....

class WholeFoodsScraper:
  # Same ...
  # Array to store the scraped stores
  scraped_stores = []
    
  # get_store_info function
  
  def parse_stores(self, data):
    # Creating an lxml Element instance
        element = fromstring(data)

        for store in element.cssselect('.views-row'):
            store_info = {}
            
            # The lxml etree css selector always returns a list, so we get
            # just the first item
            store_name = store.cssselect('.views-field-title a')[0].text
            street_address = store.cssselect('.street-block div')[0].text
            address_locality = store.cssselect('.locality')[0].text
            address_state = store.cssselect('.state')[0].text
            address_postal_code = store.cssselect('.postal-code')[0].text
            phone_number = store.cssselect('.views-field-field-phone-number div')[0].text
            
            try:
                opening_hours = store.cssselect('.views-field-field-store-hours div')[0].text
            except IndexError:
                # Stores that doesn't have opening hours are closed and should not be saved.
                # This is found while debugging, so don't worry if you get errors when you
                # run a scraper
                opening_hours = 'STORE CLOSED'
                continue
            
            full_address = "{}, {}, {} {}".format(street_address,
                                                  address_locality,
                                                  address_state,
                                                  address_postal_code)
            
            # now we add all the info to a dict
            store_info = {
                        'name': store_name,
                        'full_address': full_address,
                        'phone': phone_number,
                        'hours': opening_hours
                        }
            
            # We add the store to the scraped stores list
            self.scraped_stores.append(store_info)

Bây giờ chúng tôi chỉ cần một chức năng để gọi

    #! /usr/bin/python
    from __future__ import print_function
    import cgi, cgitb
    def index():
        data = cgi.FieldStorage()
        mydata = data['param1'].value
        return return "test"
2 cho mỗi một trong số 22 trang có các cửa hàng toàn bộ bởi trang web của tiểu bang Hoa Kỳ và sau đó phân tích dữ liệu với
    #! /usr/bin/python
    from __future__ import print_function
    import cgi, cgitb
    def index():
        data = cgi.FieldStorage()
        mydata = data['param1'].value
        return return "test"
3. Chúng tôi cũng sẽ tạo một chức năng nhỏ để lưu tất cả các dữ liệu được quét vào tệp JSON.

import json
import ... All stays the same
  
class WholeFoodsScraper:
  # Same ...
    
  def run(self):
        for page in range(22):
            # Retrieving the data
            data = self.get_stores_info(page)
            # Parsing it
            self.parse_stores(data)
            print('scraped the page' + str(page))

        self.save_data()

    def save_data(self):
        with open('wholefoods_stores.json', 'w') as json_file:
            json.dump(self.scraped_stores, json_file, indent=4)

Bây giờ máy cạo của chúng tôi đã sẵn sàng! Chúng ta chỉ cần chạy nó. Thêm điều này vào cuối tệp Python:

if __name__ == '__main__':
  scraper = WholeFoodsScraper()
  scraper.run()

Bạn có thể thấy kết quả trong tệp

    #! /usr/bin/python
    from __future__ import print_function
    import cgi, cgitb
    def index():
        data = cgi.FieldStorage()
        mydata = data['param1'].value
        return return "test"
4.

Sự kết luận

Bây giờ bạn phải hỏi, "Khi nào tôi nên sử dụng trình duyệt tự động và, tôi có nên cố gắng tái tạo các cuộc gọi AJAX không?" Câu trả lời rất đơn giản: Luôn cố gắng tái tạo các cuộc gọi AJAX trước khi thử một cái gì đó phức tạp hoặc nặng hơn như sử dụng trình duyệt tự động - hãy thử cách tiếp cận đơn giản và nhẹ hơn này!

Tương tự, bạn cũng có thể thử xây dựng máy cạo web của riêng mình bằng Node.js.


Bio của tác giả

Julio Alejandro là một nhà phát triển phần mềm tự do và kỹ sư hóa học từ Venezuela với các kỹ năng đang phát triển. Anh ấy thích làm phát triển web, quét web và tự động hóa! Anh ta làm việc chủ yếu là lập trình phía máy chủ với Python/Django/Flask. Ông cũng phát triển phía trước với các khung JavaScript như Vue hoặc React.

Làm cách nào để nhận dữ liệu từ Ajax Call?

Gửi yêu cầu Ajax..
Ví dụ: Yêu cầu JQuery Ajax. $. ....
Ví dụ: Nhận dữ liệu JSON. ....
Ví dụ: Phương thức Ajax (). ....
Ví dụ: Gửi yêu cầu bài đăng ..

Bạn có thể sử dụng Ajax với Python không?

Hãy sửa đổi mã hiện có để thực hiện tính toán với JavaScript, phía máy khách thay vì ở phía máy chủ với Python.Chúng tôi cũng có thể sử dụng AJAX để xử lý đầu vào của người dùng thay vì hiển thị một mẫu.We can also use Ajax to handle the user input rather than rendering a template.

Làm thế nào gửi và nhận dữ liệu bằng AJAX?

Ajax ({type: "Post", DataType: "json", dữ liệu: '{test: works}', url: 'Ajax/getDude. PHP', thành công: function (phản hồi) {alert (phản hồi);}}).;.
jquery..

Đối tượng nào có thể được sử dụng để truy xuất dữ liệu trong AJAX?

Các đối tượng XMLHTTPREQUEST (XHR) được sử dụng để tương tác với các máy chủ.Bạn có thể lấy dữ liệu từ URL mà không cần phải làm mới trang đầy đủ.Điều này cho phép một trang web cập nhật chỉ là một phần của trang mà không làm gián đoạn những gì người dùng đang làm.Xmlhttprequest được sử dụng rất nhiều trong lập trình AJAX. objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. XMLHttpRequest is used heavily in AJAX programming.