效果展示
前言
学了点selenium和python操作数据库
看B站文章的时候想到能不能把这些爬下来存入数据库(作者名字,标题,链接)内容就不爬了
虽然爬下来的数据没什么用,但也是一个小练习,促进自己成长
目标网页
需要用到的库
from selenium import webdriver
from time import sleep
from lxml import etree
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ChromeOptions
import pymysql
使用selenium是,总会弹出一个网页,很麻烦,使用无可视化去除浏览器窗口,规避检测
#无可视化
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#规避检测
option = ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
#规避检测
wd = webdriver.Chrome(executable_path='D:/Apycharm/pachong/chromedriver/chromedriver.exe',chrome_options=chrome_options,options=option)
打开b站专栏
#打开b站
wd.get('https://www.bilibili.com/read/home?spm_id_from=333.851.b_7072696d617279467269656e64736869704c696e6b.1')
获取源码数据并解析数据
# 获取源码数据
page_text = wd.page_source
# 解析数据
tree = etree.HTML(page_text)
现在,我们开始分析网页
按F12查看网页源代码
通过分析得出代码
先提取包含 作者名字,标题,链接 信息的 div,再对提取出来的列表进行遍历,是因为有许许多多的一种类型的div,依次取出 作者名字,链接
注意: 标题提取的时候会出现空列表,增加一个异常处理,如果列表为空,不进行提取
trrr = tree.xpath('//div[@class="article-content"]')
for li in trrr:
#作者名字
names = li.xpath('.//span[@class="nick-name"]/text()')[0]
links = li.xpath('./div[@class="article-left-block"]/a/@href')[0]
#链接
link ='https:' + links
#可能出现空列表错误 list index out of range
try:
#标题
titles = li.xpath('.//span[@class="article-title"]/@title')[0]
至此,信息已经提取完毕
下一步,进行数据库的操作
我的数据库用户root,密码000000,指定数据库bilibili,指定表名Bli
表结构如下图
上代码
try:
#标题
titles = li.xpath('.//span[@class="article-title"]/@title')[0]
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='20191007lh', database='bilibili',charset='utf8')
# 生成游标对象
cur = conn.cursor()
sql1 = "INSERT INTO Bli VALUES (%s,%s,%s)"
data = [names,titles,link]
try:
cur.execute(sql1, data) # 执行插入的sql语句
conn.commit() # 提交到数据库执行
except Exception:
# 发生错误时回滚
conn.rollback()
print("出现错误/可能与重复的值有关")
conn.close() # 关闭数据库连接
except Exception:
pass
最后,下拉页面显示提示信息,休眠1秒 使用for循环将整个代码循环运行,
wd.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print("以将第%s页存入数据库中" % i)
sleep(1)
i += 1
wd.quit()
完整代码
from selenium import webdriver
from time import sleep
from lxml import etree
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ChromeOptions
import pymysql
#无可视化
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#规避检测
option = ChromeOptions()
option.add_experimental_option('excludeSwitches',['enable-automation'])
#规避检测
wd = webdriver.Chrome(executable_path='D:/Apycharm/pachong/chromedriver/chromedriver.exe',chrome_options=chrome_options,options=option)
#打开b站
wd.get('https://www.bilibili.com/read/home?spm_id_from=333.851.b_7072696d617279467269656e64736869704c696e6b.1')
# 循环 下拉
for i in range(1, 100):
# 获取源码数据
page_text = wd.page_source
# 解析数据
tree = etree.HTML(page_text)
trrr = tree.xpath('//div[@class="article-content"]')
for li in trrr:
#作者名字
names = li.xpath('.//span[@class="nick-name"]/text()')[0]
links = li.xpath('./div[@class="article-left-block"]/a/@href')[0]
#链接
link ='https:' + links
#可能出现空列表错误 list index out of range
try:
#标题
titles = li.xpath('.//span[@class="article-title"]/@title')[0]
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='000000', database='bilibili',charset='utf8')
# 生成游标对象
cur = conn.cursor()
sql1 = "INSERT INTO Bli VALUES (%s,%s,%s)"
data = [names,titles,link]
try:
cur.execute(sql1, data) # 执行插入的sql语句
conn.commit() # 提交到数据库执行
except Exception:
# 发生错误时回滚
conn.rollback()
print("出现错误/可能与重复的值有关")
conn.close() # 关闭数据库连接
except Exception:
pass
wd.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print("以将第%s页存入数据库中" % i)
sleep(1)
i += 1
wd.quit()