我的個(gè)人微博早前有大量跟好友的頁面聊天數(shù)據(jù)兜叨,隨著時(shí)間增多穿扳,發(fā)的微博近乎上萬條衩侥,可是微博本身沒有提供數(shù)據(jù)備份功能国旷,查看了一下API文檔,從官方提供的接口取得的數(shù)據(jù)也只是有限條茫死,無法滿足需要跪但,因此萌發(fā)了寫個(gè)爬蟲用模擬登錄的方式將所有發(fā)過的微博抓取下來。
一 峦萎、先分析一下微博網(wǎng)頁版的結(jié)構(gòu)和流程:
首先是登錄屡久,需要用戶名、密碼爱榔、驗(yàn)證碼被环,登錄成功后進(jìn)入個(gè)人微博主頁,在主頁右邊有一個(gè)年份側(cè)邊欄详幽,從這里可以按時(shí)間查看所有發(fā)過的微博筛欢,這就是我主要的抓取對(duì)象了浸锨,再進(jìn)一步查看頁面結(jié)構(gòu)可知,微博按年月進(jìn)行數(shù)據(jù)讀取版姑,每一個(gè)月的微博有可能為0柱搜,也有可能有好幾頁,每一頁需要將頁面滾動(dòng)到底部幾次才會(huì)完全加載出來剥险。
二聪蘸、然后準(zhǔn)備好工具:
Python 3.6
selenium 3.3.3
火狐瀏覽器驅(qū)動(dòng) geckodriver-v0.15.0-win64
三、難點(diǎn)與重點(diǎn):
1表制、模擬登錄過程
新浪微博的網(wǎng)頁版登錄過程比起別的有一點(diǎn)小曲折健爬,它需要先輸入用戶名驗(yàn)證后才會(huì)顯示驗(yàn)證碼,不過既然是用selenium模擬么介,這些都不是問題浑劳。
verifyimg = browser.find_element_by_css_selector("img[node-type='verifycode_image']") //驗(yàn)證碼圖片
num = 0
while verifyimg.get_attribute('src') == "about:blank":
num = num + 1
if num == 5:
logger.info("驗(yàn)證碼無法加載,請重試夭拌!")
browser.quit()
return
userInput.click() //模擬點(diǎn)擊用戶輸入框以觸發(fā)驗(yàn)證碼顯示
time.sleep(8)
pwInput.click()
time.sleep(5)
模擬登錄的重點(diǎn)是對(duì)驗(yàn)證碼圖片進(jìn)行截圖保存魔熏,用于后續(xù)人工識(shí)別輸入,這一行代碼我花了半天進(jìn)行文檔查詢和編寫調(diào)試鸽扁,目前是在火狐瀏覽器上調(diào)試成功蒜绽,但是后面我將驅(qū)動(dòng)換成phantomjs,截取下來的卻是整個(gè)頁面桶现。
verifyimg.screenshot("verifycode.png")
2躲雅、用腳本將頁面拉到底部讀取數(shù)據(jù)
從selenium官方文檔上查到的方法,版本是3.3.3骡和。
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
3相赁、判斷某個(gè)年月的微博是否有下一頁
由于為了方便抓取,設(shè)置了多個(gè)參數(shù)慰于,于是為了判斷下一頁钮科,各種語句調(diào)試了一天,才整出下面這段代碼:
//pages:要下載的頁面數(shù)婆赠;page:當(dāng)前第幾頁绵脯;pagecount:總頁面數(shù)
if (not pages) or (not isinstance(pages[0], int)) or (pages[0] > pagecount) or (pages[0] >= pagecount - page) or (pages[0] <= 0): #不傳翻頁數(shù)或者翻頁數(shù)參數(shù)錯(cuò)誤
if page < pagecount:
page = page + 1
getWeiboHtml(datenum, url, count, page)
elif page == pagecount:
logger.info("保存完畢!")
return
elif (pages[0] > 0) and (pages[0] < pagecount - page):
if pages[0] == 1:
logger.info("保存完畢休里!")
return
else:
page = page + 1
flip = pages[0]-1
getWeiboHtml(datenum, url, count, page, flip)
else:
return
4蛆挫、獲取到第一條微博和最新一條微博的日期
第一條微博日期是通過點(diǎn)擊微博主頁的時(shí)間線,獲取網(wǎng)址中的stat_date字段數(shù)據(jù)妙黍。
最新一條微博日期直接就從登錄后的微博主頁內(nèi)容字段中解析悴侵。
5、日志系統(tǒng)
這次這個(gè)爬蟲項(xiàng)目拭嫁,不光學(xué)到了selenium的使用可免,還學(xué)到了Python自帶的日志系統(tǒng)的使用筒繁,受益匪淺。
下面的函數(shù)使日志系統(tǒng)從文件里讀取配置巴元。
def setup_logging(
default_path='logconfig.json',
default_level=logging.INFO,
env_key='LOG_CFG'):
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'r') as f:
config = json.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
然后在程序中引入日志進(jìn)行記錄:
import logging.config
logger = logging.getLogger(__name__)
6毡咏、selenium的安裝
裝selenium的時(shí)候并不順利,一開始是想用chrome瀏覽器的逮刨,但是下載了chrome的驅(qū)動(dòng)后無法使用呕缭,折騰了好久最后改用了火狐。
四修己、進(jìn)階
目前微博是以html文件的形式保存下來了恢总,但是還需要繼續(xù)編寫解析器從html里面提取出結(jié)構(gòu)化的數(shù)據(jù),還有區(qū)別原創(chuàng)與轉(zhuǎn)發(fā)睬愤,對(duì)表情和圖片進(jìn)行下載等片仿,待以后有時(shí)間需要一一進(jìn)行解決。
目前寫的爬蟲僅能在自己的機(jī)子上以命令行的形式運(yùn)行尤辱,想要給朋友使用都不行砂豌,因此還要繼續(xù)學(xué)習(xí)Python的打包與界面化。