2015-06-02 34 views
5

Tôi đang sử dụng thư viện python-requests để thực hiện yêu cầu của mình.Cách nhanh để kiểm tra xem hình ảnh trên URL từ xa có tồn tại trong python

Trên trang chủ của trang web, tôi nhận được một loạt các hình ảnh và hiển thị chúng cho người dùng. Đôi khi những hình ảnh đó bị xóa và tôi nhận được một url hình ảnh bị hỏng.

Vì vậy, tôi muốn kiểm tra xem hình ảnh có tồn tại hay không.

Dưới đây là những gì tôi đã làm:

items = Item.objects.filter(shop__is_hidden=False, is_hidden=False).order_by("?")[:16] 

existing_items = [] 

for item in items: 
    response = requests.head(item.item_low_url) 
    if response.status_code == 200: 
     existing_items.append(item) 

Nhưng nó được dùng lâu hơn một chút so với tôi muốn.

Có cách nào nhanh hơn không?

Trả lời

4

Yêu cầu của bạn đang chặn và đồng bộ, đó là lý do tại sao phải mất một chút thời gian. Nói một cách đơn giản, nó có nghĩa là yêu cầu thứ hai không bắt đầu, cho đến khi yêu cầu đầu tiên kết thúc.

Hãy nghĩ nó giống như một băng chuyền với một bó hộp và bạn có một công nhân để xử lý mỗi hộp.

Nhân viên chỉ có thể xử lý một hộp tại một thời điểm; và anh ta phải chờ quá trình xử lý được thực hiện trước khi anh ta có thể bắt đầu xử lý một hộp khác (nói cách khác, anh ta không thể lấy một hộp từ thắt lưng, thả nó ở đâu đó để được xử lý, quay lại và chọn một cái khác).

Để giảm thời gian cần thiết để hộp quá trình, bạn có thể:

  1. Giảm thời gian cần thiết để xử lý mỗi hộp.
  2. Làm cho nó để nhiều hộp có thể được xử lý cùng một lúc (nói cách khác, công nhân không phải đợi).
  3. Tăng số lượng đai và công nhân và sau đó chia các hộp giữa các đai.

Chúng tôi thực sự không thể làm # 1 vì sự chậm trễ này là từ mạng (bạn có thể giảm thời gian chờ, nhưng điều này không được khuyến nghị).

Thay vào đó những gì chúng tôi muốn làm là # 2 - vì việc xử lý một hộp là độc lập, chúng tôi không cần phải chờ một hộp để kết thúc để bắt đầu xử lý tiếp theo.

Vì vậy, chúng tôi muốn làm như sau:

  1. Nhanh chóng gửi nhiều yêu cầu đến một máy chủ cho các URL cùng lúc.
  2. Đợi mỗi người trong số họ hoàn thành (độc lập với nhau).
  3. Thu thập kết quả.

Có nhiều cách để thực hiện việc này được liệt kê trong documentation for requests; đây là ví dụ sử dụng grequests:

import grequests 

# Create a map between url and the item 
url_to_item = {item.item_low_url: item for item in items} 

# Create a request queue, but don't send them 
rq = (grequests.head(url) for url in url_to_item.keys()) 

# Send requests simultaneously, and collect the results, 
# and filter those that are valid 

# Each item returned in the Response object, which has a request 
# property that is the original request to which this is a response; 
# we use that to filter out the item objects 

results = [url_to_item[i.request.url] 
      for i in filter(lambda x: x.status_code == 200, 
          grequests.map(rq)))] 
+0

Cảm ơn câu trả lời toàn diện của bạn. Nó chắc chắn nhanh hơn, nhưng 'kết quả' hóa ra lại là một danh sách các đối tượng' Response', không phải Item, điều đáng ngạc nhiên. Bất kỳ ý tưởng để sửa lỗi này? –

+0

Lý do một loạt các đối tượng phản hồi là vì đó là sự trở lại từ 'grequests.map (rq)'.Xem bản cập nhật để có cách ánh xạ trở lại mục 'mục' ban đầu. –

+0

Cảm ơn bạn rất nhiều :) –

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