上篇文章我非常high的爬取了一個正常網(wǎng)頁的數(shù)據(jù)
對是正常
這次研究的就是那些“不正辰淞迹”的網(wǎng)頁 當時是我太天真 后面發(fā)現(xiàn)水又深
介于現(xiàn)在JS H5的大趨勢 大部分網(wǎng)站都是混入了JS數(shù)據(jù)加載 數(shù)據(jù)是延遲加載的
這樣如果我們用原始的urllib.open(url) 加載出來的都是還沒有加載js數(shù)據(jù)之前的 所以爆炸了
所以按照上篇文章那么正常的提取數(shù)據(jù)顯然不可取了 那畢竟那是靜態(tài)的 戰(zhàn)場上 敵人也不會像抗日神劇劇情一樣讓你當靶子不是
我當時的想法就是要讓讓網(wǎng)頁JS渲染數(shù)據(jù)加載完全了 我們才開始解析 這樣才行 想想就行了 然而我并不會
后面查了一些資料
- 無非兩種實現(xiàn)
1 分析JS源碼 找出請求 自己模擬實現(xiàn) 難度比較高 麻煩
2 模擬瀏覽器實現(xiàn) 三方庫多 簡單 但是效率會慢一點
然后搜到了很多相關的庫 這里使用的是 Selenium + PhantomJs 網(wǎng)上推薦比較多
- Selenium是一個用于Web應用程序測試的工具
- Phantom JS是一個服務器端的 JavaScript API 的 WebKit
看了一下Selenium的Api 發(fā)現(xiàn)沒有PhantomJS 他也可以使用FireFox來實現(xiàn)如同PhantomJs的功能
介于網(wǎng)上都是推薦PhantomJS 所以我也這樣實現(xiàn)
Selenium就像一個大容器 里面放著PhantomJs來實現(xiàn)JS的渲染 我們直接操作Selenium的Api就行
這次選取的目標是 淘寶模特的網(wǎng)站 為什么是這個呢 除了美女多
還有就是我學習的資料就是用的這個
Python學習的網(wǎng)站這個里面就是用這個作為實例
但是這個后續(xù)可能因為淘寶改版了網(wǎng)站結構 他的例子不能成功 所以我才研究JS的動態(tài)加載
開始套路 這里環(huán)境Windows
1 安裝Selenium 用Pip 安裝 如果Pip不能被找到 記得設置環(huán)境變量Python/Script
2 下載PhantomJs 然后將 解壓后的執(zhí)行文件放在被設置過環(huán)境變量的地方 不設置的話 后續(xù)代碼就要設置 所以這里直接放進來方便
這里檢查一下
能找到 說明Ok
下面是全部實現(xiàn)代碼
#coding=utf-8
__author__ = 'Daemon'
import urllib2,re,os,datetime
from selenium import webdriver
class Spider:
def __init__(self):
self.page=1
self.dirName='MMSpider'
#這是一些配置 關閉loadimages可以加快速度 但是第二頁的圖片就不能獲取了打開(默認)
cap = webdriver.DesiredCapabilities.PHANTOMJS
cap["phantomjs.page.settings.resourceTimeout"] = 1000
#cap["phantomjs.page.settings.loadImages"] = False
#cap["phantomjs.page.settings.localToRemoteUrlAccessEnabled"] = True
self.driver = webdriver.PhantomJS(desired_capabilities=cap)
def getContent(self,maxPage):
for index in range(1,maxPage+1):
self.LoadPageContent(index)
#獲取頁面內容提取
def LoadPageContent(self,page):
#記錄開始時間
begin_time=datetime.datetime.now()
url="https://mm.taobao.com/json/request_top_list.htm?page="+str(page)
self.page+=1;
USER_AGENT='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'
headers = {'User-Agent':USER_AGENT }
request=urllib2.Request(url,headers=headers)
response=urllib2.urlopen(request)
#正則獲取
pattern_link=re.compile(r'<div.*?class="pic-word">.*?<img src="(.*?)".*?'
r'<a.*?class="lady-name".*?href="(.*?)".*?>(.*?)</a>.*?'
r'<em>.*?<strong>(.*?)</strong>.*?'
r'<span>(.*?)</span>'
,re.S)
items=re.findall(pattern_link,response.read().decode('gbk'))
for item in items:
#頭像噪猾,個人詳情凑耻,名字鹰祸,年齡鬼悠,地區(qū)
print u'發(fā)現(xiàn)一位MM 名字叫%s 年齡%s 坐標%s'%(item[2],item[3],item[4])
print u'%s的個人主頁是 %s'%(item[2],item[1])
print u'繼續(xù)獲取詳情頁面數(shù)據(jù)...'
#詳情頁面
detailPage=item[1]
name=item[2]
self.getDetailPage(detailPage,name,begin_time)
def getDetailPage(self,url,name,begin_time):
url='http:'+url
self.driver.get(url)
base_msg=self.driver.find_elements_by_xpath('//div[@class="mm-p-info mm-p-base-info"]/ul/li')
brief=''
for item in base_msg:
print item.text
brief+=item.text+'\n'
#保存?zhèn)€人信息
icon_url=self.driver.find_element_by_xpath('//div[@class="mm-p-model-info-left-top"]//img')
icon_url=icon_url.get_attribute('src')
dir=self.dirName+'/'+name
self.mkdir(dir)
#保存頭像
try:
self.saveIcon(icon_url,dir,name)
except Exception,e:
print u'保存頭像失敗 %s'%e.message
#開始跳轉相冊列表
images_url=self.driver.find_element_by_xpath('//ul[@class="mm-p-menu"]//a')
images_url=images_url.get_attribute('href')
try:
self.getAllImage(images_url,name)
except Exception,e:
print u'獲取所有相冊異常 %s'%e.message
end_time=datetime.datetime.now()
#保存?zhèn)€人信息 以及耗時
try:self.saveBrief(brief,dir,name,end_time-begin_time)
except Exception,e:
print u'保存?zhèn)€人信息失敗 %s'%e.message
#獲取所有圖片
def getAllImage(self,images_url,name):
self.driver.get(images_url)
#只獲取第一個相冊
photos=self.driver.find_element_by_xpath('//div[@class="mm-photo-cell-middle"]//h4/a')
photos_url=photos.get_attribute('href')
#進入相冊頁面獲取相冊內容
self.driver.get(photos_url)
images_all=self.driver.find_elements_by_xpath('//div[@id="mm-photoimg-area"]/a/img')
self.saveImgs(images_all,name)
def saveImgs(self,images,name):
index=1
print u'%s 的相冊有%s張照片, 嘗試全部下載....'%(name,len(images))
for imageUrl in images:
splitPath = imageUrl.get_attribute('src').split('.')
fTail = splitPath.pop()
if len(fTail) > 3:
fTail = "jpg"
fileName = self.dirName+'/'+name +'/'+name+ str(index) + "." + fTail
print u'下載照片地址%s '%fileName
self.saveImg(imageUrl.get_attribute('src'),fileName)
index+=1
def saveIcon(self,url,dir,name):
print u'頭像地址%s %s '%(url,name)
splitPath=url.split('.')
fTail=splitPath.pop()
fileName=dir+'/'+name+'.'+fTail
print fileName
self.saveImg(url,fileName)
#寫入圖片
def saveImg(self,imageUrl,fileName):
print imageUrl
u=urllib2.urlopen(imageUrl)
data=u.read()
f=open(fileName,'wb')
f.write(data)
f.close()
#保存?zhèn)€人信息
def saveBrief(self,content,dir,name,speed_time):
speed_time=u'當前MM耗時 '+str(speed_time)
content=content+'\n'+speed_time
fileName=dir+'/'+name+'.txt'
f=open(fileName,'w+')
print u'正在獲取%s的個人信息保存到%s'%(name,fileName)
f.write(content.encode('utf-8'))
#創(chuàng)建目錄
def mkdir(self,path):
path=path.strip()
print u'創(chuàng)建目錄%s'%path
if os.path.exists(path):
return False
else:
os.makedirs(path)
return True
spider=Spider()
#獲取前5頁
spider.getContent(5)
效果如下 只獲取了第一個相冊的第一頁的 如果要全部的 還要涉及到模擬下滑加載更多這里先不作了解:
妹子不得來告我吧
聲明一遍 如果有不能展示的 聯(lián)系我 我會刪掉的丹壕。箩兽。。
現(xiàn)在來分析一下 實現(xiàn)過程
- 第一頁 任務列表 正常網(wǎng)頁 看看結構 來用正則獲取任務詳情頁面
- 頁面詳情 使用PhantomJS 來加載 然后根據(jù)Xpath來獲取 XPath是個寶貝啊 特別好用很粗暴一下子可以拿到想要的
上篇文章有相關資料 不做詳細分析 這個丑丑的正則
-
基本信息獲取 觀察結構
對應的代碼
獲取基本信息 -
然后頭像也是一樣
Paste_Image.png
獲取頭像 -
獲取相冊地址 進入相冊頁面
獲取相冊鏈接
最后在相冊里面獲取第一頁展示的
到此結束 保存相關信息的代碼 上面也給出了 這里不做詳細說明
基本分析 就是用google瀏覽器的F12 來分析結構 然后 抽取內容 感覺Python 相關資料很少啊 尤其是中文的
這個PhantomJs 之所以這里給出分享過程 因為我確實在Google 知乎(度娘更不用說了)上面搜索相關資料很少 別人也就說用這個 也沒說咋用 對于新手來講 還是希望能有一個完整的過程分析
寫的時候聽的歌
我等到花兒都謝了
我睡不著的時候會不會有人陪著我
我難過的時候會不會有人安慰我
我想說話的時候會不會有人了解我
我忘不了你的時候你會不會來疼我