上篇文章 使用 XPath 提取網頁信息 之后,將鏈接中的內容下載至本地,需要使用到 urllib2 。更多見:iii.run
urllib2 簡介
urllib2提供一個基礎函數urlopen,通過向指定的URL發出請求來獲取數據。最簡單的形式就是:
import urllib2
response = urllib2.urlopen('http://www.mmmxcc.cn/')
html = response.read()
可以將上述代碼看作兩個步驟,我們指定一個域名并發送請求
request=urllib2.request('http://www.mmmxcc.cn/')
接著服務端響應來自客戶端的請求
response=urllib2.urlopen(request)
我們可以發現title這個地方本來應該是中文的,但因為編碼的原因,導致出現亂碼。通過將html頁面重新用"utf-8"編碼,可以解決這個問題。
將獲得的response保存至本地
使用Xpath表達式提取圖片鏈接
詳見上一文章 http://feiyang.li/2016/12/13/get_html/index.html ,關于XPath和beautifulsoup,可以參考python中的beautifulsoup和xpath有什么異同點?
這里需要導入lxml,代碼格式如下。
import requests
from lxml import etree
html = requests.get("http://jandan.net/ooxx")
html.encoding = 'utf-8'
selector = etree.HTML(html.text)
content = selector.xpath('//ol[@class = "commentlist"]//@src')
單獨運行 以上代碼可以獲得
設置保存的位置
需要使用到os庫中的 os.chdir(r"")函數,""中間插入地址。注意這個位置必須是存在的,如果位置不存在,函數會報錯。因為該函數的意義是:將工作空間從python代碼所在位置,改為指定的這個位置。
模擬正常瀏覽器下載圖片(如果Python下載的圖片不顯示 )
有時你會碰到,程序也對,但是服務器拒絕你的訪問。這是為什么呢?
問題出在請求中的頭信息(header)。 有的服務端有潔癖,不喜歡程序來觸摸它。
這個時候你需要將你的程序偽裝成瀏覽器來發出請求。請求的方式就包含在header中。
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36',
'Cookie': 'AspxAutoDetectCookieSupport=1',
}
request = urllib2.Request(imgurl, None, header)
response = urllib2.urlopen(request)
可以看到urllib2.Request()里邊加入了一個header,用于模擬瀏覽器訪問,第二個位置None表示data,用Python官方文檔的說法:*Sometimes you want to send data to a URL (often the URL will refer to a CGI (Common Gateway Interface) script [1] or other web application). With HTTP, this is often done using what’s known as a POST request. *
暫時我們用不著,所以不深究,等我碰到這個問題了再說。
為圖片命名(下載圖片只有一張)
在獲得response之后,將圖片直接保存為某個特定名字的話。會導致之后抓取到的圖片頂替掉之前的圖片,導致圖片看起來只有一張。
with open("%s.jpg" %name, "wb") as f:
f.write(response.read())
print(imgurl)
name += 1
使用with as語句,將文件名保存為%s.jpg,類似于C語言的輸出。循環結束的時候name++,保證文件名不重復。
使用with as 函數
Python’s with statement provides a very convenient way of dealing with the situation where you have to do a setup and teardown to make something happen. A very good example for this is the situation where you want to gain a handler to a file, read data from the file and the close the file handler.
有一些任務,可能事先需要設置,事后做清理工作。對于這種場景,Python的with語句提供了一種非常方便的處理方式。一個很好的例子是文件處理,你需要獲取一個文件句柄,從文件中讀取數據,然后關閉文件句柄。
Without the with statement, one would write something along the lines of:
如果不用with語句,代碼如下:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
使用with as之后代碼為:
with open("%s.jpg" %name, "wb") as f:
f.write(response.read())
總結
本文通過XPath表達式提取頁面圖片鏈接,使用urllib2下載,其中使用header模仿瀏覽器訪問。解決了以下問題:
- Python下載的圖片不顯示
- 下載圖片只有一張
- 設置保存的位置
- 使用with f函數
效果如下:
完整代碼
# coding=utf-8
import requests
import urllib2
import os
from lxml import etree
html = requests.get("http://cl.d5j.biz/htm_mob/7/1612/2172569.html")
html.encoding = 'utf-8'
selector = etree.HTML(html.text)
content = selector.xpath('//table//img/@src')
for imgurl in content:
name = imgurl[-9:];
os.chdir(r"D:")
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36',
'Cookie': 'AspxAutoDetectCookieSupport=1',
}
request = urllib2.Request(imgurl, None, header) #刻意增加頭部header,否則本行與下一行可以寫為:response = urllib2.urlopen(imgurl)
response = urllib2.urlopen(request)
f = open(name , 'wb')
f.write(response.read())
f.close()
print(imgurl)
代碼重新修改了一下,上手運行會發現D盤有驚喜哦~
加入print(imgurl),運行起來更洋氣~