任務(wù)需求是爬取微博的內(nèi)容和評論。一開始我是準(zhǔn)備直接用正常的爬蟲來做,但是發(fā)現(xiàn)微博上的內(nèi)容幾乎都是動態(tài)加載生成的。所以了解了一下就學(xué)習(xí)使用·selenium自動化測試工具來爬取相關(guān)數(shù)據(jù)。
首先是不登錄微博,發(fā)現(xiàn)只能查看最多二十條數(shù)據(jù),這自然限制太大所以還是需要實現(xiàn)登錄后再爬取。
1.登錄微博
由于微博現(xiàn)在的登錄不能只輸入賬號密碼,所以通過查找了一些方法后選用了注入cookie來實現(xiàn)自動登錄。而想要注入的cookie需要自己先登錄獲得。這里直接使用了各位大佬給出的方法。實現(xiàn)掃碼登錄后獲取cookie。
from selenium import webdriver
from time import sleep
import json
from selenium.webdriver.common.by import By
if __name__ == '__main__':
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://weibo.com/login.php')
sleep(6)
a = driver.find_element(By.XPATH, '//*[@id="pl_login_form"]/div/div[1]/div/a[2]')
a.click()
sleep(10)
dictCookies = driver.get_cookies() # 獲取list的cookies
jsonCookies = json.dumps(dictCookies) # 轉(zhuǎn)換成字符串保存
with open('微博_cookies.txt', 'w') as f:
f.write(jsonCookies)
print('cookies保存成功!')
2.通過獲取到的cookie實現(xiàn)自動登錄然后爬取用戶微博內(nèi)容和評論
2.1打開瀏覽器,進入到登錄頁面。這里我最大化窗口了。
# 打開瀏覽器,進入到微博登錄頁面
def browser_initial():
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://weibo.com/login.php')
return browser
2.2實現(xiàn)自動化登錄
# 將已經(jīng)登錄獲得的cookie寫入,實現(xiàn)自動登錄
def log_csdn(browser):
with open('微博_cookies.txt', 'r', encoding='utf8') as f:
listCookies = json.loads(f.read())
# 往browser里添加cookies
for cookie in listCookies:
cookie_dict = {
'domain': '.weibo.com',
'name': cookie.get('name'),
'value': cookie.get('value'),
"expires": '',
'path': '/',
'httpOnly': False,
'HostOnly': False,
'Secure': False
}
#print(cookie_dict)
browser.add_cookie(cookie_dict)
sleep(1)
browser.get('https://weibo.com/login.php')
登錄后的頁面如下圖
?
2.3搜索內(nèi)容并且爬取
這時候需要在左上角的搜索框輸入自己需要搜索的用戶,然后通過按回車來實現(xiàn)搜索
?得到新的頁面里可以看到最上方會顯示相關(guān)的賬戶,找到相關(guān)元素并點擊即可
最后進入到用戶的完整頁面
這時侯就可以開始爬取用戶的微博信息和評論了。由于微博的內(nèi)容是動態(tài)加載的,通過F12可以看到一開始是僅展示六條內(nèi)容的元素
通過滑動,元素會逐漸增加,但是上限是12個,并且后面會出現(xiàn)元素順序和微博內(nèi)容順序不符的情況。如果單單爬取微博的內(nèi)容,不爬評論那還好,只需要定位到每一個元素塊,獲取其內(nèi)部的text文本然后處理一下就可以獲得自己想要的信息。但是由于還要爬取相應(yīng)的評論內(nèi)容,并且評論還要和微博內(nèi)容相對應(yīng),所以不能直接進行爬取。
這里我選擇微博內(nèi)容里的時間元素里的href
?
?通過點擊這個a標(biāo)簽,可以跳轉(zhuǎn)到該條微博的詳情頁面
這時候就可以分塊爬起微博的內(nèi)容以及轉(zhuǎn)發(fā)數(shù)、評論數(shù)、點贊數(shù)和評論的內(nèi)容了。要注意的是這里的轉(zhuǎn)發(fā)數(shù)評論數(shù)這些可能存在多個,比如此圖里是轉(zhuǎn)發(fā)他人微博,他人微博里也有轉(zhuǎn)發(fā)數(shù)這些。還有就是評論的內(nèi)容有可能是開啟精選后的,和普通的評論內(nèi)容要做判斷。?爬取完微博內(nèi)容和評論后點擊上方的返回按鈕,回到之前的頁面。
hrefs = []
# 搜索內(nèi)容
def search(username):
# 等待元素出現(xiàn)再進行下一步
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "woo-pop-ctrl")))
# 獲取搜索框元素
searchinput = browser.find_element(By.CLASS_NAME, 'woo-input-main')
# 將要搜索的內(nèi)容寫入搜索框
searchinput.send_keys(username)
# 等待0.5秒后按回車
sleep(0.2)
searchinput.send_keys(Keys.ENTER)
# 轉(zhuǎn)移句柄到新的頁面
new_window = browser.window_handles[-1]
# 關(guān)閉原來的頁面
browser.close()
# 窗口轉(zhuǎn)移到新的頁面
browser.switch_to.window(new_window)
# 等待
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "card-wrap")))
# 定位用戶微博頭像并點擊
weibo = browser.find_element(By.XPATH, '//div[@class="card card-user-b s-brt1 card-user-b-padding"]/div/a')
weibo.click()
new_window = browser.window_handles[-1]
browser.switch_to.window(new_window)
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "vue-recycle-scroller__item-view")))
# 微博一次最多給12條內(nèi)容的元素,并且給出的元素不保證順序。
# 所以第一次進入頁面的時候獲取所有的內(nèi)容元素,a標(biāo)簽里的href唯一,所以將其提取出來
for t in range(3):
a = browser.find_elements(By.XPATH, '//div[@class="woo-box-item-flex head_main_3DRDm"]/div/div[2]/a')
# 在獲取到的列表里進行篩選,已經(jīng)爬取過的微博就跳過
for i in range(len(a)):
if a[i].get_attribute("href") in hrefs:
print("已經(jīng)搜索過")
continue
else:
print("還沒搜索過")
# 每次都向下滑動400像素,大致符合一條微博的高度
changepage(400)
# sleep(0.5)
newpage = a[i].get_attribute("href")
# 打印href
print(newpage)
hrefs.append(newpage)
# print(comments)
# 打印已經(jīng)搜索的微博內(nèi)容數(shù)
print(len(hrefs))
# 使用js腳本來點擊元素,否則可能出現(xiàn)元素不在網(wǎng)頁上,無法交互的報錯
# a[i].click()
browser.execute_script("arguments[0].click();", a[i])
# 不要直接用href去請求,否則點擊返回的時候會直接回到微博首頁面
# browser.get(newpage)
sleep(0.5)
# 爬取具體內(nèi)容頁面的內(nèi)容和評論
findall()
sleep(0.2)
# 找到返回按鈕并點擊
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.XPATH,
'//div[@class="woo-box-flex woo-box-alignCenter Bar_left_2J3kl Bar_hand_2VAG1"]/i')))
back = browser.find_element(By.XPATH,
'//div[@class="woo-box-flex woo-box-alignCenter Bar_left_2J3kl Bar_hand_2VAG1"]/i')
back.click()
?
text = []
# 將頁面向下滑動px像素
def changepage(px):
browser.execute_script("window.scrollBy(0, {})".format(px))
# 爬取微博的內(nèi)容和評論
def findall():
# 等待頁面元素加載
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "Feed_body_3R0rO")))
body = browser.find_element(By.CLASS_NAME, 'Feed_body_3R0rO')
# 通過換行來劃分內(nèi)容
bodytext = body.text.split("\n")
print(bodytext)
# 找到轉(zhuǎn)發(fā)評論點贊的元素,但是如果有微博內(nèi)容為轉(zhuǎn)發(fā)他人的微博,則存在兩個footer元素,
# 所以尋找多個,然后取最后那一個
footer = browser.find_elements(By.TAG_NAME, 'footer')
footertext = footer[-1].text.split("\n")
print(footertext[1])
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "Detail_box_3Jeom")))
try:
prompt = browser.find_element(By.CLASS_NAME, "RepostCommentList_tip_2O5W-")
print(prompt.text)
t = False
except:
t = True
print(t)
while t:
try:
browser.find_element(By.XPATH, '//div[@class="Bottom_text_1kFLe"]')
t = False
except:
t = True
WebDriverWait(browser, 15).until(
EC.presence_of_element_located((By.XPATH, '//div[@class="vue-recycle-scroller__item-wrapper"]')))
pagecomment = browser.find_elements(By.XPATH, '//div[@class="vue-recycle-scroller__item-view"]')
for i in pagecomment:
comment = i.text.split("\n")
if comment in text:
continue
else:
print(comment)
text.append(comment)
sleep(0.1)
changepage(600)
?最后爬取內(nèi)容和評論的總的代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-784235.html
from selenium import webdriver
from time import sleep
import json
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
text = []
hrefs = []
# 打開瀏覽器,進入到微博登錄頁面
def browser_initial():
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://weibo.com/login.php')
return browser
# 將已經(jīng)登錄獲得的cookie寫入,實現(xiàn)自動登錄
def log_csdn(browser):
with open('微博_cookies.txt', 'r', encoding='utf8') as f:
listCookies = json.loads(f.read())
# 往browser里添加cookies
for cookie in listCookies:
cookie_dict = {
'domain': '.weibo.com',
'name': cookie.get('name'),
'value': cookie.get('value'),
"expires": '',
'path': '/',
'httpOnly': False,
'HostOnly': False,
'Secure': False
}
#print(cookie_dict)
browser.add_cookie(cookie_dict)
sleep(1)
browser.get('https://weibo.com/login.php')
#print(browser.get_cookies())
#browser.refresh() # 刷新網(wǎng)頁,cookies才成功
# 搜索內(nèi)容
def search(username):
# 等待元素出現(xiàn)再進行下一步
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "woo-pop-ctrl")))
# 獲取搜索框元素
searchinput = browser.find_element(By.CLASS_NAME, 'woo-input-main')
# 將要搜索的內(nèi)容寫入搜索框
searchinput.send_keys(username)
# 等待0.5秒后按回車
sleep(0.2)
searchinput.send_keys(Keys.ENTER)
# 轉(zhuǎn)移句柄到新的頁面
new_window = browser.window_handles[-1]
# 關(guān)閉原來的頁面
browser.close()
# 窗口轉(zhuǎn)移到新的頁面
browser.switch_to.window(new_window)
# 等待
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "card-wrap")))
# 定位用戶微博頭像并點擊
weibo = browser.find_element(By.XPATH, '//div[@class="card card-user-b s-brt1 card-user-b-padding"]/div/a')
weibo.click()
new_window = browser.window_handles[-1]
browser.switch_to.window(new_window)
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "vue-recycle-scroller__item-view")))
# 微博一次最多給12條內(nèi)容的元素,并且給出的元素不保證順序。
# 所以第一次進入頁面的時候獲取所有的內(nèi)容元素,a標(biāo)簽里的href唯一,所以將其提取出來
for t in range(3):
a = browser.find_elements(By.XPATH, '//div[@class="woo-box-item-flex head_main_3DRDm"]/div/div[2]/a')
# 在獲取到的列表里進行篩選,已經(jīng)爬取過的微博就跳過
for i in range(len(a)):
if a[i].get_attribute("href") in hrefs:
print("已經(jīng)搜索過")
continue
else:
print("還沒搜索過")
# 每次都向下滑動400像素,大致符合一條微博的高度
changepage(400)
# sleep(0.5)
newpage = a[i].get_attribute("href")
# 打印href
print(newpage)
hrefs.append(newpage)
# print(comments)
# 打印已經(jīng)搜索的微博內(nèi)容數(shù)
print(len(hrefs))
# 使用js腳本來點擊元素,否則可能出現(xiàn)元素不在網(wǎng)頁上,無法交互的報錯
# a[i].click()
browser.execute_script("arguments[0].click();", a[i])
# 不要直接用href去請求,否則點擊返回的時候會直接回到微博首頁面
# browser.get(newpage)
sleep(0.5)
# 爬取具體內(nèi)容頁面的內(nèi)容和評論
findall()
sleep(0.2)
# 找到返回按鈕并點擊
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.XPATH,
'//div[@class="woo-box-flex woo-box-alignCenter Bar_left_2J3kl Bar_hand_2VAG1"]/i')))
back = browser.find_element(By.XPATH,
'//div[@class="woo-box-flex woo-box-alignCenter Bar_left_2J3kl Bar_hand_2VAG1"]/i')
back.click()
# 將頁面向下滑動px像素
def changepage(px):
browser.execute_script("window.scrollBy(0, {})".format(px))
# 爬取微博的內(nèi)容和評論
def findall():
# 等待頁面元素加載
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "Feed_body_3R0rO")))
body = browser.find_element(By.CLASS_NAME, 'Feed_body_3R0rO')
# 通過換行來劃分內(nèi)容
bodytext = body.text.split("\n")
print(bodytext)
# 找到轉(zhuǎn)發(fā)評論點贊的元素,但是如果有微博內(nèi)容為轉(zhuǎn)發(fā)他人的微博,則存在兩個footer元素,
# 所以尋找多個,然后取最后那一個
footer = browser.find_elements(By.TAG_NAME, 'footer')
footertext = footer[-1].text.split("\n")
print(footertext[1])
WebDriverWait(browser, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "Detail_box_3Jeom")))
try:
prompt = browser.find_element(By.CLASS_NAME, "RepostCommentList_tip_2O5W-")
print(prompt.text)
t = False
except:
t = True
print(t)
while t:
try:
browser.find_element(By.XPATH, '//div[@class="Bottom_text_1kFLe"]')
t = False
except:
t = True
WebDriverWait(browser, 15).until(
EC.presence_of_element_located((By.XPATH, '//div[@class="vue-recycle-scroller__item-wrapper"]')))
pagecomment = browser.find_elements(By.XPATH, '//div[@class="vue-recycle-scroller__item-view"]')
for i in pagecomment:
comment = i.text.split("\n")
if comment in text:
continue
else:
print(comment)
text.append(comment)
sleep(0.1)
changepage(600)
if __name__ == "__main__":
# 打開瀏覽器進入微博登錄頁面
browser = browser_initial()
# 使用cookie登錄微博
log_csdn(browser)
# 爬取相關(guān)用戶的評論
search("杭州地鐵")
里面的數(shù)據(jù)處理還沒做,大家可以自己打印出來后根據(jù)自己的需要進行處理。文章來源地址http://www.zghlxwxcb.cn/news/detail-784235.html
到了這里,關(guān)于使用selenium自動化工具爬取微博內(nèi)容和評論的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!