实现效果
关于selenium库
用途:
模拟人工打开浏览器并进行一些操作,类似于手机上的连点器和脚本,可以有效的解决弹窗类的反扒机制。
使用:
pip 安装 ,下载浏览器驱动 ,给驱动配置环境 ,重启pycharm测试。
关于panda库
用途:
将字典转换成dataframe并更以csv的形式导出。
使用:
pip 安装即可。
代码
from selenium import webdriver # 从selenium导入webdriver
from selenium.webdriver.common.by import By # 内置定位器策略集
from selenium.webdriver.support.wait import WebDriverWait # 用于实例化一个Driver的显式等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from pandas.core.frame import DataFrame
option = webdriver.ChromeOptions()
option.add_argument("headless")
driver = webdriver.Chrome() # chrome_options=option 这个参数设置之后可以隐藏浏览器
driver.get('https://www.zhihu.com/question/284206141') # 修改这里的地址
def waitFun():
js = """
let equalNum = 0;
window.checkBottom = false;
window.height = 0;
window.intervalId = setInterval(()=>{
let currentHeight = document.body.scrollHeight;
if(currentHeight === window.height){
equalNum++;
if(equalNum === 2){
clearInterval(window.intervalId);
window.checkBottom = true;
}
}else{
window.height = currentHeight;
window.scrollTo(0,window.height);
window.scrollTo(0,window.height-1000);
}
},1500)"""
# 这个暂停一下是因为要等待页面将下面的内容加载出,这个 1500 可以根据自己的网络快慢进行适当的调节
# 这里需要往上移动一下,因为不往上移动一下发现不会加载。
driver.execute_script(js)
# selenium 可以获取 浏览器中 js 的变量。调用的js return
def getHeight(nice):
# 这里获取 js 中的 checkBottom 变量,作为到底部时进行停止。
js = """
return window.checkBottom;
"""
return driver.execute_script(js)
try:
# 先触发登陆弹窗。
WebDriverWait(driver, 40, 1).until(EC.presence_of_all_elements_located(
(By.CLASS_NAME, 'Modal-backdrop')), waitFun())
# 点击空白关闭登陆窗口
ac = driver.find_element_by_xpath('//body/div[4]/div[1]/div[1]/div[1]/div[2]/button[1]/*[1]')
ActionChains(driver).move_to_element(ac).double_click(ac).perform()
# 当滚动到底部时
WebDriverWait(driver, 40, 3).until(getHeight, waitFun())
# 获取回答
answerElementArr = driver.find_elements_by_css_selector('.RichContent-inner') # .List-item
# 获取id
idElementArr = driver.find_elements_by_css_selector('div.AuthorInfo-head > span.UserLink') # .List-item
# 获取日期
dateElementArr = driver.find_elements_by_css_selector('.ContentItem-time') # .List-item
# 获取标题
title = driver.find_element_by_class_name('QuestionHeader-title')
filename = title.text
# 创建list
a = []
b = []
c = []
# id写入
for uid in idElementArr:
a.append(uid.text)
# 答案写入
for answer in answerElementArr:
b.append(answer.text)
# date写入
for date in dateElementArr:
c.append(date.text)
# 将列表转换成字典
d = {"id": a, "answer": b, "date": c}
# 创建 Dataframe
dateframe = DataFrame(d)
# 到出 csv文件
dateframe.to_csv("./{}.csv".format(title.text),index=False)
print(len(answerElementArr))
print(len(idElementArr))
print(len(dateElementArr))
print('爬取问题 ' + title.text + str(len(answerElementArr)) + ' 条,存入到csv文件中')
finally:
driver.close() # close the driver
这套代码是在 python 使用 selenium 爬虫知乎 的基础上进行了完善,将自动关闭登陆窗的机制改为xpath定位元素双击,然后自动向下滑动,并将结果以csv的形式写入方便以后进行数据处理。