2013-11-20 14 views
6

Ý tưởng rất đơn giản: Tôi cần gửi song song nhiều yêu cầu HTTP.Cách tốt nhất để gửi nhiều yêu cầu HTTP bằng Python 3 là gì?

Tôi đã quyết định sử dụng thư viện requests-futures cho điều đó, về cơ bản sẽ sinh ra nhiều chuỗi.

Hiện tại, tôi có khoảng 200 yêu cầu và vẫn còn khá chậm (mất khoảng 12 giây trên máy tính xách tay của tôi). Tôi cũng đang sử dụng một cuộc gọi lại để phân tích cú pháp câu trả lời (như được đề xuất trong tài liệu thư viện). Ngoài ra, có một quy tắc của ngón tay cái để tìm ra số lượng tối ưu của các chủ đề như là một chức năng của số lượng yêu cầu, là có bất kỳ?

Về cơ bản, tôi đã tự hỏi liệu tôi có thể tăng tốc các yêu cầu đó thêm nữa không.

+0

Phiên bản python nào? Tùy chọn stdlib của bạn thay đổi khá đáng kể từ 2,7 đến 3,3. – roippi

+0

Tôi sẽ đề xuất mô-đun luồng + urllib, nhưng gói bạn liên kết về cơ bản cũng giống như vậy. Theo như điều chỉnh số lượng các chủ đề, tôi đã chạy 25 hoặc lâu hơn mà không có một vấn đề trên máy tính xách tay của tôi (MacBook Pro, bộ xử lý 3,2 GHz, RAM 16 GB). – BenDundee

+0

@roippi Tôi đang sử dụng python 3.3 –

Trả lời

6

Vì bạn đang sử dụng python 3.3, tôi sẽ đề xuất giải pháp stdlib mà bạn sẽ không tìm thấy trong chuỗi được liên kết bởi @ njzk2: concurrent.futures.

Đây là giao diện cấp cao hơn chỉ giao dịch trực tiếp với threading hoặc multiprocessing nguyên thủy. Bạn nhận được một giao diện Executor để xử lý tổng hợp và báo cáo không đồng bộ.

Các tài liệu có một ví dụ đó là về cơ bản được áp dụng trực tiếp đến tình hình của bạn, vì vậy tôi sẽ chỉ cần thả nó ở đây:

import concurrent.futures 
import urllib.request 

URLS = #[some list of urls] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
      # do json processing here 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 

Bạn có thể thay urllib.request cuộc gọi với requests cuộc gọi, nếu bạn muốn. Tôi có xu hướng thích requests hơn, vì lý do rõ ràng.

API đi một chút như thế này: tạo một bó của Future các đối tượng đại diện cho việc thực thi không đồng bộ chức năng của bạn. Sau đó, bạn sử dụng concurrent.futures.as_completed để cung cấp cho bạn trình lặp trên Future trường hợp của mình. Nó sẽ mang lại cho họ khi chúng được hoàn thành.

Đối với câu hỏi của bạn:

Ngoài ra, là có một quy tắc của ngón tay cái để tìm ra số lượng tối ưu của đề như một chức năng của số lượng yêu cầu, là có bất kỳ?

Quy tắc chung, không. Nó phụ thuộc vào quá nhiều thứ, bao gồm tốc độ kết nối internet của bạn. Tôi sẽ nói nó không thực sự phụ thuộc vào số lượng yêu cầu bạn có, nhiều hơn về phần cứng bạn đang chạy.

May mắn thay, khá dễ dàng để tinh chỉnh số tiền max_workers kwarg và tự kiểm tra. Bắt đầu từ 5 hoặc 10 luồng, tăng dần theo số gia số 5. ​​Bạn có thể nhận thấy hiệu suất cao tại một số điểm, và sau đó bắt đầu giảm khi chi phí bổ sung thêm chủ đề vượt qua mức tăng biên của tăng song song (là một từ) .

+0

Hãy để tôi nói, có _are_ giới hạn về các chủ đề mở mà tôi đã chạy vào trước trên các máy AWS của chúng tôi, nhưng không phải trên máy tính xách tay của tôi. Vấn đề được nêu ở đây: http://www.alak.cc/2011/11/python-threaderror-cant-start-new.html – BenDundee

+0

@roippi có bạn đã xem xét mô-đun yêu cầu tương lai mà tôi đã tôn kính trong bài đăng gốc của mình ? Nó thực hiện khá nhiều cùng một mã. –

+0

@NikolayDerkach, tôi không có, nhưng nhìn vào nó .. huh! Nó kết thúc tốt đẹp về cơ bản ở trên vào một cuộc gọi API, điều này khá hay. Một trong những vấn đề với điều đó là nếu nó là chậm/misbehaving, bạn không có bất kỳ recourse cho tinh chỉnh nó. Ví dụ, bạn có thể dễ dàng cụ thể hóa mã ở trên khi có lỗi. Dù sao chúc may mắn :) – roippi

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