经过之前的介绍,学会了requests,BeautifulSoup库的简单使用,现在将介绍selenium+chromedriver的方式来实现爬虫
1.首先准备库
pycharm的话在File->Settings->
然后
对了,在国内,可以设置镜像,不然会很不方便,有时候安装不上,有时候搜索不出来
镜像:
https://mirrors.aliyun.com/pypi/simple/
https://pypi.tuna.tsinghua.edu.cn/simple/
设置镜像如下
回归正题,如上方法安装下面这几个库
2.准备chromedriver
对于chromedriver,百度chromedriver,下载对应你chrome浏览器版本的版本
比如我的浏览器版本
在淘宝镜像下载,我选择了81.4044.69相对接近我的版本,测试可用
下载之后,直接copy到你的python安装路径
方法不止这一种
还可以直接copy到你pycharm的project文件里面
还可以设置环境变量
还可以在创建chromedriver对象的时候添加路径参数
还可以…
作者推荐正使用的方法,一劳永逸
3.分析斗鱼的HTML框架
可以看到,每一个li就是一个主播
每个li里面找到相应信息的位置
简单分析完毕
4.终于可以撸代码了
from selenium import webdriver # 用于创建浏览器对象
from selenium.webdriver.chrome.options import Options # 用于创建参数设置对象
from selenium.webdriver.common.by import By # 用于查找元素时的简单
from selenium.webdriver.support.ui import WebDriverWait # 用于设置浏览器等待DOM对象创建完成之后再进行获取
from selenium.webdriver.support import expected_conditions as EC # 同上
from bs4 import BeautifulSoup
import pandas
import time
import random
URL = 'https://www.douyu.com/directory/all'
driver = {}
op = {}
soup = {}
slogans = []
hotValues = []
names = []
zones = []
singleInfor = []
# 获取网页信息
def getInfor():
global op, driver, URL
# 打开网页
op = Options()
# 为设置对象添加属性
op.add_argument('--window-size=1600,600')
# 这个参数为了防止服务器在console查询window.navigator.webdriver这个参数来识别是否使用selenium访问
# 在正常情况下,该参数位undefined,但在使用了selenium之后会变为true,对op设置以下参数会避免这个问题发生
# 同时,在chromeVer>=79版本,google修复非headless下window.navigator.webdriver为undefined的问题
# 如果要爬的网站不行,可以试试回滚浏览器,然后再设置下面这句话
# 斗鱼没有该反爬机制,故不用设置该参数
# op.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome(options=op)
driver.get(URL)
# 每页信息处理
def inforHandle():
global soup, zones, names, hotValues, slogans, singleInfor, driver
# 煲汤
soup = BeautifulSoup(driver.page_source, 'lxml')
# 找到每个主播的li标签,这里斗鱼是将每个主播所有信息放在一个li标签里面
soup = soup.find_all(class_='layout-Module-container layout-Cover ListContent')
for i in soup:
temp = i.find_all(class_='layout-Cover-item')
for j in temp:
zones.append(j.find(class_='DyListCover-zone').text)
slogans.append(j.find(class_='DyListCover-intro').text)
hotValues.append(j.find(class_='DyListCover-hot').text)
names.append(j.find(class_='DyListCover-user').text)
singleInfor.append(names)
singleInfor.append(hotValues)
singleInfor.append(zones)
singleInfor.append(slogans)
# 换页
def nextPages():
for i in range(150):
inforHandle()
# 每次等待的时间用随机数
sleepTime = round(random.random(), 1) + 2
print('已处理第', i, '页...', '用时', sleepTime)
time.sleep(sleepTime)
# 这里是等待下一页按钮加载完成时菜点击
nextPage = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '.dy-Pagination-next>.dy-Pagination-item-custom')))
nextPage.click()
# 存文件
def saveInCsv():
# 用pandas很方便,储存也用方便的csv文件,到时候要再excel文件使用,可以在excel直接导入就行
df = pandas.DataFrame({'主播名': names, '分区': zones, '口号': slogans, '热度': hotValues})
df.to_csv('text.csv', index=False, sep=',')
def main():
getInfor()
nextPages()
try:
main()
finally:
saveInCsv()
# 最开始写第一页时的测试函数
def test():
for i in range(len(names)):
for j in range(4):
print(singleInfor[j][i], end=' ')
print('\n', end='')
#关闭浏览器驱动
# driver.close()
代码比较简单,同时注释比较详细,特别说明一些代码API
1.对于等待元素加载完毕的API
2.对于数据储存
这里使用了
pandas官方文档
selenium官方文档
最后,附上
爬取结果