بايثون:احصل على رؤوس HTTP من استدعاء urllib2.urlopen؟
-
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.
نصائح أخرى
وماذا عن إرسال طلب HEAD بدلا من طلب GET العادي. وفيما يلي مقصوص (نسخ من أ >) يفعل ذلك بالضبط.
>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]
في الواقع، يبدو أن 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