小編身為建築師,經常需要到各種建築網站找項目的參考圖片。然而這年頭各個大師們的事務所網站大家都懂得,各種高冷或者炫酷的動畫效果讓人一次只能看一張圖,要想更高效率的看圖或者下載到高清大圖就更加麻煩了。
那麼身為新時代的設計師,有沒有簡單高效的方式來搞定這一切嗎?
有!答案就是Python爬蟲。
我們今天以著名結構建築兩棲大師卡拉特拉瓦的個人網站為例。簡單介紹下怎樣用Python爬蟲高效獲取大師的高清作品集。
用爬蟲獲取大師的作品集,其實原理上跟瀏覽網頁一樣,都是先打開項目的頁面,點開高清大圖,然後保存圖片,只不過python爬蟲的速度很快而已。
因為是爬取圖片,所以本次爬蟲沒有使用Selenium,而是選擇了純代碼的方式,這樣可以省下瀏覽器打開圖片渲染頁面的時間消耗。
整個爬蟲分為四個步驟:
訪問網站
找到有哪些項目,以及項目的詳細介紹的網頁
在項目詳細介紹的網頁找到高清大圖的地址
下載圖片
在最開始我們可以用任意一款python編輯器,新建一個空的.py的文件。然後在最開頭的地方加入我們需要用到的程序包,本次爬蟲用了Beautifulsoup包,如果沒有安裝可以按以下方法安裝。
pip install beautifulsoup4
pip3 install beautifulsoup4Beautifulsoup包安裝方法,強烈推薦使用Anaconda,這些常用包都是默認配置好的。
import requests, re, osfrom bs4 import BeautifulSoupproject_url = r'https://calatrava.com/projects.html?all=yes'def download_page(url): headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0' } data = requests.get(url, headers=headers).content.decode('utf-8') return data2.找到有哪些項目,以及項目的詳細介紹的網址
我們可以通過F12調出瀏覽器的開發者工具,看看這個網頁到底是怎麼構成的。我們可以看到所有的項目信息都在一個<div>打頭的大標籤裡。在這個標籤中,每個項目又分別對應了一個<li>的標籤,li標籤的class名是odd或者even。利用Beautifulsoup的find_all方法,我們就可以拆分出這個頁面中出現的每個項目的網頁信息,而項目的詳細地址
def parse_html(url): html = download_page(url) soup = BeautifulSoup(html, features='lxml') project_list_part=soup.find("div",{"class":"mod_cal_project_list thumb_view block"}) project_list_soup = project_list_part.find_all('li', {'class': {'odd',"even"}}) return project_list_soupdef get_project_title(project_list_soup): project_title = [] for link in project_list_soup: project_year = link.find('span', {'class': 'year'}) links = link.find('a')['href'] name = str(project_year.string) + '--'+ str(links[9:-5]) project_title.append(name) return project_titledef get_project_link(project_list_soup): project_link = [] for link in project_list_soup: links = link.find('a')['href'] links = str(r"https://calatrava.com/" + links+r"?view_mode=gallery") project_link.append(links) return project_link3.我們需要在項目詳細介紹的網頁找到高清大圖的地址。
我們依然按F12進入瀏覽器的開發者模式,進入Network標籤頁,找到項目的大圖的實際地址。再通過大圖的實際地址轉到element標籤頁中進行查找,這樣我們可以解析出隱藏在翻頁動畫背後的高清大圖的存儲結構。
在開發者模式的network標籤頁中找到高清大圖的位置
用找到的高清大圖的名稱,回到element標籤頁中Ctrl+F查找這個名稱
至此我們可以發現頁面的動畫效果是通過一個JavaScript代碼實現的,而每個項目的大圖都是結構化的存儲在這段json對象中,那我們直接用正則表達式提取出來就好了。
def parse_sub_html(project_link): html = download_page(project_link) project_soup = BeautifulSoup(html, features='lxml') project_img_links_script=project_soup.find_all("script") project_img_links=re.findall(r"'(?P<addr>files.*)', title",str(project_img_links_script)) for i in range(len(project_img_links)): project_img_links[i]=str(r"https://calatrava.com/")+project_img_links[i] print(project_img_links) print("此項目大圖數量 = "+len(project_img_links)) return project_img_linksdef save_img(links, name): headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'} os.makedirs('./Calatrava project img/', exist_ok=True) t = 1 for link in links: filename = str('./Calatrava project img/' + str(name) + '%s.jpg' % (repr(t))) print("Downloading----",str(filename)) with open(filename, "wb") as img: img.write(requests.get(link, headers=headers).content) t += 1至此我們每一個步驟的方法都寫完了,最後的最後組裝成一個main函數運行就可以搓手收圖了。
def main(): soup = parse_html(project_url) name = get_project_title(soup) link = get_project_link(soup) print(link) t = 0 while t < len(name): if link[t] == "": print("Skip it,Because it is null,Hurry coding,,Fix it later") t += 1 else: img_list = parse_sub_html(link[t]) print('Project Name is :', name[t]) save_name = str(repr(t + 1)+"-" + name[t]) save_img(img_list, save_name) print('No %s is ok' % repr(t + 1)) t += 1
if __name__ == '__main__': main()運行狀態
卡拉特拉瓦的事務所網站一共90個項目,630張高清大圖,就這樣可以自動下好了。而且這個爬蟲基本可以覆蓋市面上95%以上的事務所網站的構架了,稍微改改地址之類的操作就可以一蟲多用,是不是真香!
本文僅做python爬蟲的技術探討,請各位在法律框架下謹慎使用。