بايثون:احصل على رؤوس HTTP من استدعاء urllib2.urlopen؟

StackOverflow https://stackoverflow.com/questions/843392

  •  20-08-2019
  •  | 
  •  

سؤال

يفعل urllib2 جلب الصفحة بأكملها عندما أ urlopen تم إجراء المكالمة؟

أرغب فقط في قراءة رأس استجابة HTTP دون الحصول على الصفحة.يبدو الأمر كذلك urllib2 يفتح اتصال HTTP ثم يحصل بعد ذلك على صفحة HTML الفعلية...أم أنها تبدأ للتو في تخزين الصفحة مؤقتًا باستخدام ملف urlopen يتصل؟

import urllib2
myurl = 'http://www.kidsidebyside.org/2009/05/come-and-draw-the-circle-of-unity-with-us/'
page = urllib2.urlopen(myurl) // open connection, get headers

html = page.readlines()  // stream page
هل كانت مفيدة؟

المحلول

استخدم ال response.info() طريقة الحصول على الرؤوس

من urllib2 مستندات:

urllib2.urlopen(url[, data][, timeout])

...

تقوم هذه الدالة بإرجاع كائن يشبه الملف بطريقتين إضافيتين:

  • geturl() — يُرجع عنوان URL للمورد الذي تم استرداده، والذي يُستخدم عادةً لتحديد ما إذا تم اتباع عملية إعادة توجيه
  • info() - إرجاع المعلومات التعريفية للصفحة، مثل الرؤوس، في شكل مثيل httplib.HTTPMessage (راجع المرجع السريع لرؤوس HTTP)

لذا، على سبيل المثال، حاول التنقل خلال نتيجة response.info().headers لما تبحث عنه.

لاحظ أن التحذير الرئيسي لاستخدام httplib.HTTPMessage موثق في قضية بايثون 4773.

نصائح أخرى

في الواقع، يبدو أن urllib2 يمكن القيام به طلب HTTP الرأس.

أنreto ترتبط أعلاه، يظهر كيفية الحصول على urllib2 للقيام طلب HEAD.

وهنا بلدي يأخذ على ذلك:

import urllib2

# Derive from Request class and override get_method to allow a HEAD request.
class HeadRequest(urllib2.Request):
    def get_method(self):
        return "HEAD"

myurl = 'http://bit.ly/doFeT'
request = HeadRequest(myurl)

try:
    response = urllib2.urlopen(request)
    response_headers = response.info()

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response_headers.dict

except urllib2.HTTPError, e:
    # Prints the HTTP Status code of the response but only if there was a 
    # problem.
    print ("Error code: %s" % e.code)

إذا تحقق هذا مع شيء من هذا القبيل بروتوكول analazer شبكة يريشارك، يمكنك ان ترى انه ينوي ارسال فعلا طلب HEAD، بدلا من GET.

وهذا هو طلب HTTP واستجابة من التعليمات البرمجية أعلاه، والتي استولت عليها يريشارك:

<اقتباس فقرة>   

والرأس / doFeT HTTP / 1.1
تحمل ترميز: الهوية
المضيف:   
bit.ly اتصال: ثيق
عامل المستخدم: الثعبان urllib / 2.7

     

وHTTP / 1.1 301 منقول
الخادم: إنجن إكس
التسجيل: الأحد، 19 فبراير 2012   13:20:56 GMT
نوع المحتوى: نص / HTML. محارف = UTF-8
  ذاكرة التخزين المؤقت التحكم: الخاص؛ الحد الأقصى للسن = 90
الموقع:    http://www.kidsidebyside.org/؟p=445
MIME- الإصدار: 1.0
  المحتوى طول: 127
اتصال: على مقربة
تعيين ملف تعريف الارتباط:   _bit = 4f40f738-00153-02ed0-421cf10a، مجال = .bit.ly، تنتهي = الجمعة 17 أغسطس 13:20:56 2012؛ مسار = /. HttpOnly

ولكن، وكما ورد في أحد التعليقات في مسألة أخرى، إذا كان URL في السؤال يتضمن إعادة توجيه ثم urllib2 ستفعل طلب GET إلى الوجهة، وليس الرأس. هذا يمكن أن يكون أحد أوجه القصور الرئيسية، إذا كنت تريد حقا أن تجعل فقط طلبات الرأس.

والطلب فوق ينطوي على إعادة التوجيه. هنا هو الطلب إلى المقصد، والتي استولت عليها يريشارك:

<اقتباس فقرة>   

وGET / 2009/05 / تأتي والسحب على دائرة من بين الوحدة مع لنا / HTTP / 1.1
  استعرض ترميز: الهوية
المضيف: www.kidsidebyside.org
  إتصال: وثيقة
عامل المستخدم: الثعبان urllib / 2.7

وبديل لاستخدام urllib2 هو استخدام جو غريغوريو في httplib2 مكتبة:

import httplib2

url = "http://bit.ly/doFeT"
http_interface = httplib2.Http()

try:
    response, content = http_interface.request(url, method="HEAD")
    print ("Response status: %d - %s" % (response.status, response.reason))

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response.__dict__

except httplib2.ServerNotFoundError, e:
    print (e.message)

وهذا له ميزة استخدام طلبات الرأس لكل من طلب HTTP الأولي وطلب إعادة توجيه إلى URL الوجهة.

إليك الطلب الأول:

<اقتباس فقرة>   

والرأس / doFeT HTTP / 1.1
المضيف: bit.ly
استعرض ترميز: غزيب،   فرغ
عامل المستخدم: بيثون httplib2 / 0.7.2 (GZIP)

وهنا طلب الثاني، إلى الوجهة:

<اقتباس فقرة>   

والرأس / 2009/05 / تأتي والسحب على دائرة من بين الوحدة مع لنا / HTTP / 1.1
  المضيف: www.kidsidebyside.org
استعرض ترميز: غزيب، فرغ
  عامل المستخدم: بيثون httplib2 / 0.7.2 (GZIP)

وurllib2.urlopen لا أحد GET HTTP (أو POST في حالة توفير حجة البيانات)، وليس رأس HTTP (إذا فعلت هذا الأخير، لا يمكن أن تفعل readlines أو غيرها يصل إلى الجسم الصفحة، بالطبع).

وبطانة الأول:

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))"
def _GetHtmlPage(self, addr):
  headers = { 'User-Agent' : self.userAgent,
            '  Cookie' : self.cookies}

  req = urllib2.Request(addr)
  response = urllib2.urlopen(req)

  print "ResponseInfo="
  print response.info()

  resultsHtml = unicode(response.read(), self.encoding)
  return resultsHtml  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top