前面我們接觸到的鸡岗,都是使用requests+BeautifulSoup組合對(duì)靜態(tài)網(wǎng)頁(yè)進(jìn)行請(qǐng)求和數(shù)據(jù)解析瓶竭,若是JS生成的內(nèi)容外遇,也介紹了通過尋找API借口來獲取數(shù)據(jù)榴都。
但是有的時(shí)候索绪,網(wǎng)頁(yè)數(shù)據(jù)由JS生成湖员,API借口又死活找不著或者是API借口地址隨機(jī)變換,時(shí)間不等人瑞驱。那就只能使用Selenium了娘摔。
一、Selenium簡(jiǎn)介
Selenium是一個(gè)用于Web應(yīng)用的功能自動(dòng)化測(cè)試工具唤反,Selenium 直接運(yùn)行在瀏覽器中凳寺,就像真正的用戶在操作一樣。
由于這個(gè)性質(zhì)彤侍,Selenium也是一個(gè)強(qiáng)大的網(wǎng)絡(luò)數(shù)據(jù)采集工具肠缨,其可以讓瀏覽器自動(dòng)加載頁(yè)面,獲取需要的數(shù)據(jù)盏阶,甚至頁(yè)面截圖晒奕,或者是判斷網(wǎng)站上某些動(dòng)作是否發(fā)生。
Selenium自己不帶瀏覽器名斟,需要配合第三方瀏覽器來使用吴汪。支持的瀏覽器有Chrome、Firefox蒸眠、IE漾橙、Phantomjs等。
如果使用Chrome楞卡、FireFox或IE欲间,我們可以看得到一個(gè)瀏覽器的窗口被打開、打開網(wǎng)站午衰、然后執(zhí)行代碼中的操作。
但是藕各,讓程序在后臺(tái)中運(yùn)行更符合我們爬蟲的氣質(zhì),所以自己多使用Phantomjs作為瀏覽器載體焦除,本篇文章也以Phantomjs作介紹
Phantomjs是一個(gè)“無頭”瀏覽器激况,也就是沒有界面的瀏覽器,但是功能與普通的瀏覽器無異膘魄。
二乌逐、在Python中使用Selenium獲取QQ空間好友說說
之前使用pip安裝好了selenium,直接在代碼中import即可创葡。
下面我們以一個(gè)實(shí)際的例子——獲取一個(gè)QQ空間好友的說說信息浙踢,來簡(jiǎn)單講解一下Selenium+Phantomjs的使用。
我們需要爬取的頁(yè)面時(shí)這樣的:
QQ空間好友說說的鏈接為:http://user.qzone.qq.com/{好友QQ號(hào)}/311
我們抓取他發(fā)的說說的時(shí)間和內(nèi)容灿渴。
依舊先上代碼:
from bs4 import BeautifulSoup
from selenium import webdriver
import time
#使用selenium
driver = webdriver.PhantomJS(executable_path="D:\\phantomjs.exe")
driver.maximize_window()
#登錄QQ空間
def get_shuoshuo(qq):
????driver.get('http://user.qzone.qq.com/{}/311'.format(qq))
????time.sleep(5)
????try:
????????driver.find_element_by_id('login_div')
????????a = True
????except:
????????a = False
????if a == True:
????????driver.switch_to.frame('login_frame')
????????driver.find_element_by_id('switcher_plogin').click()
????????driver.find_element_by_id('u').clear()#選擇用戶名框
????????driver.find_element_by_id('u').send_keys('QQ號(hào)')
????????driver.find_element_by_id('p').clear()
????????driver.find_element_by_id('p').send_keys('QQ密碼')
????????driver.find_element_by_id('login_button').click()
????????time.sleep(3)
????driver.implicitly_wait(3)
????try:
????????driver.find_element_by_id('QM_OwnerInfo_Icon')
????????b = True
????except:
????????b = False
????if b == True:
????????driver.switch_to.frame('app_canvas_frame')
????????content = driver.find_elements_by_css_selector('.content')
????????stime = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail')
????????for con,sti in zip(content,stime):
????????????data = {
????????????????'time':sti.text,
????????????????'shuos':con.text
????????????}
????????????print(data)
????????pages = driver.page_source
????????soup = BeautifulSoup(pages,'lxml')
????cookie = driver.get_cookies()
????cookie_dict = []
????for c in cookie:
????????ck = "{0}={1};".format(c['name'],c['value'])
????????cookie_dict.append(ck)
????i = ''
????for c in cookie_dict:
????????i += c
????print('Cookies:',i)
????print("==========完成================")
????driver.close()
????driver.quit()
if __name__ == '__main__':
????get_shuoshuo('好友QQ號(hào)')
獲取到的數(shù)據(jù)截圖如下:
接下來我們通過講解代碼洛波,稍微了解一下Selenium的使用
三、代碼簡(jiǎn)析
1.照例骚露,導(dǎo)入需要使用的模塊:
from bs4 import BeautifulSoup
from selenium import webdriver
import time
2.使用Selenium的webdriver實(shí)例化一個(gè)瀏覽器對(duì)象蹬挤,在這里使用Phantomjs:
1driver = webdriver.PhantomJS(executable_path="D:\\phantomjs.exe")
3.設(shè)置Phantomjs窗口最大化:
1driver.maximize_window()
4.主函數(shù)部分
使用get()方法打開待抓取的URL:
1driver.get('http://user.qzone.qq.com/{}/311'.format(qq))
等待5秒后,判斷頁(yè)面是否需要登錄棘幸,通過查找頁(yè)面是否有相應(yīng)的DIV的id來判斷:
????try:
????????driver.find_element_by_id('login_div')
????????a = True
????except:
????????a = False
如果頁(yè)面存在登錄的DIV闻伶,則模擬登錄:
?????? driver.switch_to.frame('login_frame') #切換到登錄ifram
????????driver.find_element_by_id('switcher_plogin').click()
????????driver.find_element_by_id('u').clear()#選擇用戶名框
????????driver.find_element_by_id('u').send_keys('QQ號(hào)')
????????driver.find_element_by_id('p').clear()#選擇密碼框
????????driver.find_element_by_id('p').send_keys('QQ密碼')
????????driver.find_element_by_id('login_button').click()#點(diǎn)擊登錄按鈕
????????time.sleep(3)
接著,判斷好友空間是否設(shè)置了權(quán)限够话,通過判斷是否存在元素ID:QM_OwnerInfo_Icon
?try:
????????driver.find_element_by_id('QM_OwnerInfo_Icon')
????????b = True
????except:
????????b = False
如果有權(quán)限能夠訪問到說說頁(yè)面,那么定位元素和數(shù)據(jù)光绕,并解析:
?if b == True:
????????driver.switch_to.frame('app_canvas_frame')
????????content = driver.find_elements_by_css_selector('.content')
????????stime = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail')
????????for con,sti in zip(content,stime):
????????????data = {
????????????????# 'qq':qq,
????????????????'time':sti.text,
????????????????'shuos':con.text
????????????}
????????????print(data)
除了在Selenium中解析數(shù)據(jù)女嘲,我們還可以將當(dāng)前頁(yè)面保存為源碼,再使用BeautifulSoup來解析:
pages = driver.page_source
soup = BeautifulSoup(pages,'lxml')
最后诞帐,我們嘗試一下獲取Cookie欣尼,使用get_cookies():
?? cookie = driver.get_cookies()
????cookie_dict = []
????for c in cookie:
????????ck = "{0}={1};".format(c['name'],c['value'])
????????cookie_dict.append(ck)
????i = ''
????for c in cookie_dict:
????????i += c
????print('Cookies:',i)
另外,再介紹兩個(gè)Selenium的常用方法:
保存屏幕截圖:
1driver.save_screenshot('保存的文件路徑及文件名')
執(zhí)行JS腳本:
driver.execute_script("JS代碼")
對(duì)于Selenium更加詳細(xì)的操作和使用停蕉,推薦一本書《selenium webdriver(python)第三版》網(wǎng)上可以搜索到愕鼓;