首先需要配置Chrome浏览器的web scraper插件和Web应用程序测试工具Selenium Webdriver
web scraper 下载地址:https://www.webscraper.io
Selenium Webdriver 下载地址:https://docs.seleniumhq.org/projects/webdriver/
from selenium import webdriver
# Keys()类提供了键盘上几乎所有按键的方法,这个类可用来模拟键盘上的按键,包括各种组合键
from selenium.webdriver.common.keys import Keys
# 将用pandas中的DataFrame(一种二维的表格型数据结构)记录爬下的数据
import pandas as pd
from datetime import datetime
import numpy as np
import time
import os
def gethtml(url):
#指定浏览器为Chrome
browser = webdriver.Chrome()
# 访问页面
browser.get(url)
#隐式等待10秒
browser.implicitly_wait(10)
return(browser)
# 指定要爬的网址:bilibili刀剑神域主页
url = 'https://www.bilibili.com/video/av6235951?from=search&seid=7671792209137111888'
browser = gethtml(url)
print('连接成功,开始爬数据')
XPath是一个符合HTML标准的选择器,使用它可以定位到我们要用的元素在页面上的哪个位置。那么,如何获取XPath?
用Chrome浏览器访问网页 - 单击右键 - 单击“检查” - 进入web scraper界面 - 点击最左上角的箭头(会提示“Select an element in the page to inspect it”) - 在网页上点击要定位的元素 - 单击右键 - 单击“Copy” - 单击“Copy XPath” - 打开记事本 - 粘贴
# 通过XPath定位我们要爬的元素“短评”
comment_number_str = browser.find_element_by_xpath('//*[@id="app"]/div[2]/div[1]/ul/li[3]').text
1
2
# 记录短评总数, [4:-1]取第4个到倒数第1个(左闭右开), strip()剔除字符串中的空格
numcount = int(comment_number_str[4:-1].strip())
1
2
每一条用户短评所在的容器都对应一个clearfix,因此可以通过记录clearfix的数目得知我们当前页面显示的短评总数
页面默认只显示20条短评,但显然我们想要更多。通过观察,我们发现bilibili的短评在我们滑到页面底端的时候会自动加载更多,因此可以通过Webdriver的Keys()类模拟手动操作
# 通过clearfix的数目计算当前页面显示的短评数
counts = len(browser.find_elements_by_class_name('clearfix'))
# 目标是至少500条
while < 500:
html = browser.find_element_by_tag_name('html')
# 模拟键盘替我们不断滑到页面底部,刷出更多数据
html.send_keys(Keys.END)
# 获取当前页面显示的短评总数
counts = len(browser.find_elements_by_class_name('clearfix'))
print(counts)
1
2
3
4
5
6
7
8
9
10
开始爬数据了,我们想抓取的是每条短评的用户信息和短片内容,即:
1.用户名 2.给刀剑神域的评分(用✨表示) 3.评论内容 4.评论时间
# 抓取用户名
#'review-author-name'是html语言中<div class>对应的class name
authors = browser.find_elements_by_class_name('review-author-name')
#获取该tag所对应的文本
lstAuthors = [authors.text for i in range(len(authors))]
1
2
3
4
5
# 抓取点赞数
stars = browser.find_elements_by_class_name('review-stars')
#点赞数无法从'review-stars'这tag对应的text中获取,但据观察可知,其子块中icon-star-light的数目就是点赞的星星数
lstStars = [len(stars.find_elements_by_class_name(' icon-star-light')) for i in range(len(stars))]
1
2
3
4
#抓取评论内容
reviews = browser.find_elements_by_class_name('review-content')
lstReviews = [reviews.text for i in range(len
1
2
3
#抓取评论时间
review_time = browser.find_elements_by_class_name('review-author-time')
lstReviewTime = [review_time.text for i in range(len(review_time))]
1
2
3
# 组成一张comments表
comments = pd.DataFrame([lstAuthors, lstStars, lstReviews, lstReviewTime])
comments = comments.T
1
2
3
# 给表格的每列加上名字'author', 'stars', 'comment', 'time'
comments.columns = ['author', 'stars', 'comment', 'time' ]
comments.to_csv('/Users/elvis/Desktop/my_data.csv', index=False)
comments.to_csv('/Users/elvis/Desktop/my_data.csv', encoding = 'utf_8_sig')
1
2
3
4
完整代码
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pandas as pd
from datetime import datetime
import numpy as np
import time
import os
def gethtml(url):
browser = webdriver.Chrome()
browser.get(url)
browser.implicitly_wait(10)
return(browser)
url = 'https://www.bilibili.com/video/av6235951?from=search&seid=7671792209137111888'
browser = gethtml(url)
print('连接成功,开始爬数据')
# 括号中的XPath的获取方式:Scrapy
comment_number_str = browser.find_element_by_xpath('//*[@id="app"]/div[2]/div[1]/ul/li[3]').text
# 记录短评总数, [4:-1]取第4个到倒数第1个(左闭右开), strip()剔除字符串中的空格
numcount = int(comment_number_str[4:-1].strip())
counts = len(browser.find_elements_by_class_name('clearfix'))
while counts < 500:
html = browser.find_element_by_tag_name('html')
html.send_keys(Keys.END)
counts = len(browser.find_elements_by_class_name('clearfix'))
print(counts)
# 抓取用户名
#'review-author-name'是html语言中<div class>对应的class name
authors = browser.find_elements_by_class_name('review-author-name')
#获取该tag所对应的文本
lstAuthors = [authors.text for i in range(len(authors))]
# 抓取点赞数
stars = browser.find_elements_by_class_name('review-stars')
#点赞数无法从'review-stars'这tag对应的text中获取,但据观察可知,其子块中icon-star-light的数目就是点赞的星星数
lstStars = [len(stars.find_elements_by_class_name(' icon-star-light')) for i in range(len(stars))]
#抓取评论内容
reviews = browser.find_elements_by_class_name('review-content')
lstReviews = [reviews.text for i in range(len
#抓取评论时间
review_time = browser.find_elements_by_class_name('review-author-time')
lstReviewTime = [review_time.text for i in range(len(review_time))]
# 组成一张comments表
comments = pd.DataFrame([lstAuthors, lstStars, lstReviews, lstReviewTime])
comments = comments.T
comments.columns = ['author', 'stars', 'comment', 'time' ]
comments.to_csv('/Users/elvis/Desktop/my_data.csv', index=False)
comments.to_csv('/Users/elvis/Desktop/my_data.csv', encoding = 'utf_8_sig')
---------------------
【转载】
作者:christianus
原文:https://blog.csdn.net/christianus/article/details/83962431
|
|