2009-02-16 29 views
43

Tôi hiện đang cố gắng đăng nhập vào một trang web bằng cách sử dụng Python, tuy nhiên trang web dường như đang gửi một cookie và một câu lệnh chuyển hướng trên cùng một trang. Python dường như đang theo dõi chuyển hướng đó, ngăn cản tôi đọc cookie được gửi bởi trang đăng nhập. Làm cách nào để ngăn chặn url của urllib (hoặc urllib2) của Python thực hiện theo chuyển hướng?Làm thế nào để ngăn chặn urllib của Python (2) theo một chuyển hướng

+0

Du plicate: http://stackoverflow.com/questions/110498/is-there-an-easy-way-to-request-a-url-in-python-and-not-follow-redirects/110808 –

+0

một câu hỏi tương tự: http://stackoverflow.com/questions/9890815/python-get-headers-only-using-urllib2 – newtover

Trả lời

33

Bạn có thể làm một vài điều:

  1. Xây dựng HTTPRedirectHandler của riêng bạn mà chặn mỗi redirect
  2. Tạo một thể hiện của HTTPCookieProcessor và cài đặt mở đó để bạn có quyền truy cập vào các cookiejar.

Đây là một điều nhỏ nhanh chóng cho thấy cả hai

import urllib2 

#redirect_handler = urllib2.HTTPRedirectHandler() 

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler): 
    def http_error_302(self, req, fp, code, msg, headers): 
     print "Cookie Manip Right Here" 
     return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers) 

    http_error_301 = http_error_303 = http_error_307 = http_error_302 

cookieprocessor = urllib2.HTTPCookieProcessor() 

opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor) 
urllib2.install_opener(opener) 

response =urllib2.urlopen("WHEREEVER") 
print response.read() 

print cookieprocessor.cookiejar 
+0

Dường như bạn không sử dụng' redirect_handler = urllib2.HTTPRedirectHandler() 'trong ví dụ này. Bạn sẽ hiển thị một ví dụ thứ hai? –

+0

Bạn đúng, tôi không sử dụng redirect_handler. Thay vào đó, tôi đã tạo trình xử lý chuyển hướng của riêng mình. Tôi sẽ chỉnh sửa để xóa. – pope

+0

Tại sao bạn không cần phải khởi tạo 'MyHTTPRedirectHandler', mà là chuyển lớp vào phương thức' build_opener() '? – Benjamin

11

urllib2.urlopen gọi build_opener() trong đó sử dụng danh sách này của các lớp xử lý:

handlers = [ProxyHandler, UnknownHandler, HTTPHandler, 
HTTPDefaultErrorHandler, HTTPRedirectHandler, 
FTPHandler, FileHandler, HTTPErrorProcessor] 

Bạn có thể thử gọi urllib2.build_opener(handlers) mình với một danh sách mà bỏ qua HTTPRedirectHandler, sau đó gọi phương thức open() vào kết quả để mở URL của bạn. Nếu bạn thực sự không thích chuyển hướng, bạn thậm chí có thể gọi số urllib2.install_opener(opener) cho công cụ mở không chuyển hướng của riêng bạn.

Có vẻ như vấn đề thực sự của bạn là urllib2 không hoạt động theo cách bạn muốn. Xem thêm How to use Python to login to a webpage and retrieve cookies for later usage?

+6

* Bạn có thể thử gọi urllib2.build_opener (trình xử lý) cho mình với một danh sách bỏ qua HTTPRedirectHandler, sau đó gọi phương thức open() trên kết quả để mở URL của bạn. * Vâng, tài liệu cho urllib2.build_opener() nói điều này * Các cá thể của các lớp sau ** sẽ nằm trước các trình xử lý **, trừ khi các trình xử lý chứa chúng, các cá thể của chúng hoặc các lớp con của chúng: ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler , HTTPErrorProcessor. * Dường như ommiting 'HTTPRedirectHandler' sẽ không hoạt động ... –

3

Câu hỏi này được hỏi trước here.

CHỈNH SỬA: Nếu bạn phải xử lý các ứng dụng web kỳ quặc, có lẽ bạn nên thử dùng mechanize. Đó là một thư viện tuyệt vời mô phỏng trình duyệt web. Bạn có thể kiểm soát chuyển hướng, cookie, làm mới trang ... Nếu trang web không dựa vào [rất nhiều] trên JavaScript, bạn sẽ nhận được cùng rất độc đáo với cơ giới hóa.

28

Nếu tất cả bạn cần là dừng chuyển hướng, sau đó là một cách đơn giản để làm điều đó. Ví dụ: tôi chỉ muốn nhận cookie và cho hiệu suất tốt hơn, tôi không muốn được chuyển hướng đến bất kỳ trang nào khác. Ngoài ra tôi hy vọng mã được giữ như 3xx. chúng ta hãy sử dụng 302 ví dụ.

class MyHTTPErrorProcessor(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     code, msg, hdrs = response.code, response.msg, response.info() 

     # only add this line to stop 302 redirection. 
     if code == 302: return response 

     if not (200 <= code < 300): 
      response = self.parent.error(
       'http', request, response, code, msg, hdrs) 
     return response 

    https_response = http_response 

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), MyHTTPErrorProcessor) 

Bằng cách này, bạn thậm chí không cần phải đi vào urllib2.HTTPRedirectHandler.http_error_302()

trường hợp Tuy nhiên, phổ biến hơn là chúng ta chỉ đơn giản là muốn dừng lại chuyển hướng (theo yêu cầu):

class NoRedirection(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     return response 

    https_response = http_response 

Và thường sử dụng nó theo cách này:

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(NoRedirection, urllib2.HTTPCookieProcessor(cj)) 
data = {} 
response = opener.open('http://www.example.com', urllib.urlencode(data)) 
if response.code == 302: 
    redirection_target = response.headers['Location'] 
+1

Chỉ cần những gì tôi cần, và rất ngắn gọn 'lớp NoRedirection() '- bạn thậm chí không có để lưu trữ' mã, msg, hdrs' - Cảm ơn Alan. –

+0

Bạn đã đúng! Và tôi đã xóa dòng như bạn đã đề xuất. Cảm ơn Xtof. –

+0

Có thể sử dụng phương pháp này để giữ URL chuyển hướng thực tế không? – AdjunctProfessorFalcon

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