python爬蟲入門 實(shí)戰(zhàn)(六)---用webdriver實(shí)現(xiàn)微博批量自動(dòng)關(guān)注


需求:
博主之前有一段時(shí)間突然不想玩微博了,然后正好表弟想玩呼畸,就給他用了痕支,手機(jī)綁定也換成了他的號(hào)碼。近期突然又想要玩蛮原,就重新開了個(gè)號(hào)卧须。新號(hào)微博空空的徒河,也沒有什么關(guān)注灌砖。于是就產(chǎn)生了兩個(gè)需求,正好可以借這個(gè)機(jī)會(huì)學(xué)習(xí)一下自動(dòng)化測試工具webdriver的基本使用:
1誊酌、將原微博的博文搬到新賬號(hào)
2蹦漠、用新賬號(hào)關(guān)注原微博的所有關(guān)注

說明:
這一篇是python爬蟲入門 實(shí)戰(zhàn)(五)---用webdriver實(shí)現(xiàn)批量自動(dòng)發(fā)微博的姊妹篇椭员,實(shí)現(xiàn)的是第二個(gè)需求,我們繼續(xù)來學(xué)習(xí)webdriver的使用笛园。

涉及:
使用webdriver實(shí)現(xiàn):
1隘击、尋找單個(gè)元素(element)
2、尋找一組具有相同屬性的元素
3研铆、點(diǎn)擊按鈕
4闸度、獲取元素的屬性
5、獲取元素包含的文本

本篇目錄:
1.思路
2.登錄微博
3.進(jìn)入目標(biāo)用戶關(guān)注列表蚜印,獲取未關(guān)注用戶id莺禁。
4.利用獲取到的id進(jìn)入目標(biāo)博主主頁,進(jìn)行關(guān)注操作
5.完整代碼
6.效果演示動(dòng)圖
7.參考


思路:

1窄赋、登錄微博
2哟冬、進(jìn)入目標(biāo)用戶(博主原微博)關(guān)注列表,獲取未關(guān)注用戶id
3忆绰、利用獲取到的id進(jìn)入目標(biāo)博主主頁浩峡,進(jìn)行關(guān)注操作

登錄微博

在上一篇教程python爬蟲入門 實(shí)戰(zhàn)(五)---用webdriver實(shí)現(xiàn)微博“搬家”(1)里的第三部分【用webdriver啟動(dòng)瀏覽器登錄微博】有思路和代碼的詳細(xì)說明。此篇不再贅述错敢。

進(jìn)入目標(biāo)用戶關(guān)注列表翰灾,獲取未關(guān)注用戶id缕粹。

1、先手動(dòng)登錄微博纸淮,進(jìn)入到目標(biāo)用戶的關(guān)注列表平斩,觀察url鏈接的構(gòu)造:

圖1.目標(biāo)用戶關(guān)注列表
http://weibo.com/p/1005052622535523/follow?from=page_100505&wvr=6&mod=headfollow#place

1、咽块?后的參數(shù)并不重要可以直接刪去绘面,重新加上 page 參數(shù)可以指定頁碼。
2侈沪、p/后的那串?dāng)?shù)字是100505+‘用戶 id ’

所以我們可以登錄以后揭璃,用一個(gè)循環(huán)遍歷所有的頁碼數(shù)構(gòu)造 url 鏈接,用
driver.get 方法訪問亭罪,即可訪問所有的關(guān)注列表瘦馍。

2、接下來看如何獲取一頁列表中所有的未關(guān)注用戶的 id 应役。

定位到【關(guān)注】按鈕情组,發(fā)現(xiàn)可以找到我們要的用戶 id (即圖中紅框里的 “uid” )。所以扛吞,我們只要找到這個(gè)元素獲取它的 “action-data” 屬性呻惕,用字符串切割和切片即可得到用戶 id 字符串。

另外滥比,我們只需關(guān)注未關(guān)注的用戶亚脆,所以已關(guān)注用戶的 id 我們是不需要的。再定位到【已關(guān)注】按鈕盲泛,對比兩個(gè)元素的屬性差異濒持。如下兩個(gè)截圖:

圖2.定位到關(guān)注按鈕
圖3.定位到已關(guān)注按鈕

我們可以發(fā)現(xiàn)它們都有 “action-type” 這個(gè)屬性,而且不同寺滚。所以我們可以用這個(gè)屬性來區(qū)分未關(guān)注用戶和已關(guān)注用戶柑营。思路總結(jié)成一句話就是,找到本頁中所有
action-type="follow" 的 a 標(biāo)簽村视,獲取 “action-data” 屬性并截取其中的 uid 官套。

因?yàn)榉?hào)條件的元素有多個(gè)(每頁有多個(gè)用戶的關(guān)注按鈕),所以用driver.find_elements(注意蚁孔,比上篇教程中的方法 driver.find_element 多一個(gè) “s”奶赔,返回的是 list )來查找一組目標(biāo)元素。用 element.get_attribute 來獲取目標(biāo)屬性杠氢。

獲取用戶 id 的代碼如下:

# 獲取某用戶的關(guān)注列表中 登錄用戶未關(guān)注的用戶
def get_followlist_unf(self,uid,page):
    url='http://weibo.com/p/100505'+uid+'/follow'+'?page='+str(page)# 關(guān)注列表頁
    self.driver.get(url)
    a_list=self.driver.find_elements_by_xpath('//a[@action-type="follow"]')# 找到所有的關(guān)注按鈕上的 a 標(biāo)簽元素
    
    uid_list=[]
    for a in a_list:
        action_data=a.get_attribute('action-data')# 獲取 action-data 屬性
        uid=action_data.split('&')[-3].split('=')[1]# 獲取uid的值
        uid_list.append(uid)# 將uid加入到list中
    return uid_list # 返回本頁所有的uid

action_data 屬性例子 :

action-data="refer_sort=followlist&refer_flag=followlist&uid=1785997537&fnick=黃思琦-&f=1"

獲取 uid 的那一行站刑,是將 action_data 屬性的字符串值從‘&’符號(hào)分割,[-3]索引到分割結(jié)果的倒數(shù)第三個(gè)鼻百,獲得字符串 uid="用戶id"绞旅,再從“=”分割摆尝,[1]索引到分割結(jié)果的第二個(gè),也就是 uid 的值因悲。

利用獲取到的id進(jìn)入目標(biāo)博主主頁堕汞,進(jìn)行關(guān)注操作

**1、手動(dòng)進(jìn)入一個(gè)未關(guān)注用戶的主頁囤捻,查看 url 結(jié)構(gòu)臼朗。如下圖: **

圖4.未關(guān)注用戶主頁
http://weibo.com/u/2392717877?refer_flag=1005050006_&is_hot=1

1邻寿、同樣的蝎土,?后面的參數(shù)沒有用绣否,可以直接刪除不用誊涯。
2、u/后面就是用戶的id
3蒜撮、有些用戶可能有個(gè)性域名暴构,地址與普通用戶不一樣,但是沒關(guān)系段磨,用 id 構(gòu)造的 url (如以上)一樣可以訪問到用戶主頁取逾。

2、找到【關(guān)注】按鈕苹支,進(jìn)行點(diǎn)擊砾隅。

我們定位到【關(guān)注】按鈕,對應(yīng)的元素是一個(gè) div 下的 a 標(biāo)簽债蜜,這個(gè) div 具有屬性 node-type="focusLink"晴埂,所以我們可以用 xpath語法定位到這個(gè)元素⊙岸ǎ回顧xpath語法參考XPath 教程儒洛。

圖5.定位關(guān)注按鈕

關(guān)注操作的代碼如下:

driver.get('http://weibo.com/u/'+uid)
focuslink=driver.find_element_by_xpath('//div[@node-type="focusLink"]/a')
focuslink.click()

像上一篇教程說的一樣,需要用 WebDriverWait(driver,10) 方法等待加載(10是超時(shí)時(shí)間狼速,可以替換成其他值)琅锻。具體使用可以參考上一篇教程,或者Python selenium 三種等待方式詳解WebDriverWait等設(shè)置等待時(shí)間和超時(shí)時(shí)間這兩篇向胡。

所以第二行改為:

focuslink=WebDriverWait(driver,10).until(lambda x:x.find_element_by_xpath('//div[@node-type="focusLink"]/a'))

3恼蓬、點(diǎn)擊了關(guān)注以后,有兩種情況需要處理捷枯。

第一種:關(guān)注成功

圖6.關(guān)注成功

第二種:請輸入驗(yàn)證碼

圖7.請輸入驗(yàn)證碼

這兩種情況可以通過定位彈出浮窗的標(biāo)題頭來區(qū)別滚秩,定位到標(biāo)題頭:

圖8.定位到標(biāo)題頭

所以我們只需要用driver.find_element_by_class_name方法來定位到該元素,再用element.get_attribute("innerHTML")來獲取元素的包含文本淮捆。

進(jìn)一步根據(jù)這個(gè)文本進(jìn)行判斷即可郁油,如果成功本股,可以什么都不做,或者輸出成功提示桐腌,如果需要輸入驗(yàn)證碼拄显,因?yàn)閷τ诔鯇W(xué)者過于復(fù)雜,我們不進(jìn)行破解案站,等待兩分鐘后再次調(diào)用關(guān)注該用戶的方法進(jìn)行重試躬审。(經(jīng)過嘗試,一般等待2~5分鐘再關(guān)注即不會(huì)彈出驗(yàn)證碼蟆盐,下次碰到驗(yàn)證碼承边,同樣進(jìn)行等待。)

代碼如下:

def follow(self,uid):
    self.driver.get('http://weibo.com/u/'+uid)
    focuslink=WebDriverWait(driver,10).until(lambda x:x.find_element_by_xpath('//div[@node-type="focusLink"]/a'))
    focuslink.click()
    # 點(diǎn)完關(guān)注后石挂,檢查頁面是否有需要輸入驗(yàn)證碼博助,如果有的話,等待2分鐘重新關(guān)注該用戶
    try:
        title=WebDriverWait(driver,10).until(lambda x:x.find_element_by_class_name('W_layer_title'))
        title_txt=title.get_attribute('innerHTML')
        if title_txt==u'關(guān)注成功':
            print u'關(guān)注用戶:'+uid+u' 成功痹愚!'
        elif title_txt==u'請輸入驗(yàn)證碼':
            print u'需要輸入驗(yàn)證碼富岳,等待120s……'
            time.sleep(120)# 休息兩分鐘再試一次
            print u'等待結(jié)束,重試'
            self.follow(uid)# 再次調(diào)用本方法
    except: 
        pass

這里加了一個(gè) try 和 except拯腮,是為了應(yīng)對什么浮窗都不彈出窖式,找不到標(biāo)題元素的情況,如果找不到即視為已成功關(guān)注动壤,什么都不做萝喘,pass掉即可。

由于有些用戶的關(guān)注列表里有城市的主頁狼电,這些城市主頁的 uid 比較特殊蜒灰,拼接成之前的用戶主頁 url 后會(huì)跳轉(zhuǎn)到主頁面 home ,為了應(yīng)對這種情況肩碟,我們還需要一個(gè) try 和 except 來防止找不到【關(guān)注】按鈕的情況强窖,同樣的,找不到關(guān)注按鈕(即異常)削祈,我們什么都不做翅溺,直接pass掉,不關(guān)注城市主頁髓抑。

修改后的代碼見完整代碼部分咙崎。

圖9.城市

以上是關(guān)注一個(gè)用戶的操作,批量關(guān)注即遍歷之前獲取到的用戶id的list吨拍,循環(huán)調(diào)用這個(gè)方法即可褪猛。

完整代碼:

相關(guān)代碼已上傳github:py_study
weibo_op_driver模塊在項(xiàng)目中的weibo文件夾中。

1羹饰、weibo_op_driver模塊中的爬取關(guān)注列表的方法:

    # 獲取某用戶的關(guān)注列表中 登錄用戶未關(guān)注的用戶
    def get_followlist_unf(self,uid,page):
        url='http://weibo.com/p/100505'+uid+'/follow'+'?page='+str(page)# 關(guān)注列表頁
        self.driver.get(url)
        a_list=self.driver.find_elements_by_xpath('//a[@action-type="follow"]')# 找到所有的關(guān)注按鈕上的 a 標(biāo)簽元素
        
        uid_list=[]
        for a in a_list:
            action_data=a.get_attribute('action-data')# 獲取 action-data 屬性
            uid=action_data.split('&')[-3].split('=')[1]# 獲取uid的值
            uid_list.append(uid)# 將uid加入到list中
        return uid_list # 返回本頁所有的uid

2伊滋、weibo_op_driver模塊中的關(guān)注與批量關(guān)注方法:

# 關(guān)注用戶
def follow(self,uid):
    self.driver.get('http://weibo.com/u/'+uid)
    try:
        focuslink=self.wait.until(lambda x:x.find_element_by_xpath('//div[@node-type="focusLink"]/a'))
        focuslink.click()
        # 點(diǎn)完關(guān)注后碳却,檢查頁面是否有需要輸入驗(yàn)證碼,如果有的話笑旺,等待2分鐘重新關(guān)注該用戶
        try:
            title=self.wait.until(lambda x:x.find_element_by_class_name('W_layer_title'))
            title_txt=title.get_attribute('innerHTML')
            if title_txt==u'關(guān)注成功':
                print u'關(guān)注用戶:'+uid+u' 成功昼浦!'
            elif title_txt==u'請輸入驗(yàn)證碼':
                print u'需要輸入驗(yàn)證碼,等待120s……'
                time.sleep(120)# 休息兩分鐘再試一次
                print u'等待結(jié)束筒主,重試'
                self.follow(uid)
        except:
            pass
    except:
        pass

# 批量關(guān)注(參數(shù)可能包含自身id)
def follow_uidlist(self,uid_list):# 參數(shù)為uid的一個(gè)list
    for uid in uid_list:
        if uid==self.uid_login:# 如果是自己的id关噪,跳過
            continue
        
        # 是未關(guān)注用戶,則關(guān)注
        self.follow(uid)

3乌妙、主方法代碼:

operator=WBoperator()
operator.login('account', 'password')# 填入你的微博賬號(hào)密碼
for i in range(41):# 博主原微博有41頁的關(guān)注列表
    page=i+1# 頁碼
     
    uid_list_unf=operator.get_followlist_unf('2622535523', page)
    operator.follow_uidlist(uid_list_unf)
    print u'第'+str(page)+u'頁關(guān)注完畢使兔!'

效果演示動(dòng)圖

圖10.批量自動(dòng)關(guān)注動(dòng)圖展示

參考

XPath 教程
Python selenium 三種等待方式詳解
WebDriverWait等設(shè)置等待時(shí)間和超時(shí)時(shí)間

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冠胯,隨后出現(xiàn)的幾起案子火诸,更是在濱河造成了極大的恐慌锦针,老刑警劉巖荠察,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奈搜,居然都是意外死亡悉盆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門馋吗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來焕盟,“玉大人,你說我怎么就攤上這事宏粤〗徘蹋” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵绍哎,是天一觀的道長来农。 經(jīng)常有香客問我,道長崇堰,這世上最難降的妖魔是什么沃于? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮海诲,結(jié)果婚禮上繁莹,老公的妹妹穿的比我還像新娘。我一直安慰自己特幔,他們只是感情好咨演,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚯斯,像睡著了一般薄风。 火紅的嫁衣襯著肌膚如雪零院。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天村刨,我揣著相機(jī)與錄音告抄,去河邊找鬼。 笑死嵌牺,一個(gè)胖子當(dāng)著我的面吹牛打洼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逆粹,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼募疮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了僻弹?” 一聲冷哼從身側(cè)響起阿浓,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹋绽,沒想到半個(gè)月后芭毙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卸耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年退敦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚣抗。...
    茶點(diǎn)故事閱讀 38,643評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侈百,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翰铡,到底是詐尸還是另有隱情钝域,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布锭魔,位于F島的核電站例证,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赂毯。R本人自食惡果不足惜战虏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望党涕。 院中可真熱鬧烦感,春花似錦、人聲如沸膛堤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绿渣,卻和暖如春朝群,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背中符。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工姜胖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淀散。 一個(gè)月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓右莱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親档插。 傳聞我的和親對象是個(gè)殘疾皇子慢蜓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容