爬虫实战(一)Python+selenium自动化获取数据存储到Mysql中

  行话说得好,“爬虫学得好,牢饭吃到饱!”哈哈博主是因这句话入的坑,不为别的就为邀大家一起铁窗泪(bushi),本人虽小牛一只,但是喜爱捣鼓技术,有兴趣的小伙伴们可以共同探讨,也欢迎各位大佬们的指点,愿共同进步!

从Selenium自动化测试到Mysql数据库

  这次计划是翻墙爬取外网某网站https://metrics.torproject.org/rs.html#details/0E300A0942899B995AE08CEF58062BCFEB51EEDF页面的内容,页面中除了正常的文本数据外,还包含了数张js加载的历史数据统计图,将爬取的文本数据直接以字符形式插入表中,图片数据需要处理为二进制后存入。素材使用的工具是Pycharm+python3.7(个人相当推荐Pycharm,不用考虑python版本于库版本是否匹配的问题,设置黑色的界面风格很有让人写代码的冲动,而且3月4号刚上线chatgpt插件),武器库呢采用的是反爬利器selenium web自动化测试,使用版本是3.141.0。从python连接数据库使用的是Pymysql1.0.2。数据库选用的是Mariadb,没找到免费Mysql,民间还是开源的Mariadb呼声更高。
目标

Selenium自动化测试

   selenium的好处在于对于一般网页的反爬虫手段有着很好的反制策略,例如常见的有请求头反爬虫,这个也是最简单的,如果不给定请求头,对方服务器就不会理你,需要设置的参数有User-Agent、Referer和Cookie。还包括有的网站会使用js接口传递数据。甚至有时你会发现自己的请求语句完全正确但是就是定位到页面元素,那就可能是使用了iframe框架,可以理解为网页嵌套。能够做到这些手段的网站不多,对于数据十分金贵的知网算的上一个,这里挖个小坑后面实战项目会有的。对于selenium还不熟悉的小伙伴,博主推荐Selenium with Python中文翻译文档https://selenium-python-zh.readthedocs.io/en/latest/

  1. 库文件
from selenium import webdriver
import pymysql as sql
import time
import random
  1. Webdriver初始化

  webdriver要和自己的chrome浏览器版本相对应(使用火狐浏览器也是可以的),不知道下载哪个版本来这里http://chromedriver.storage.googleapis.com/index.html

self.url="https://metrics.torproject.org/rs.html#details/0E300A0942899B995AE08CEF58062BCFEB51EEDF"
self.driver_path=r"D:\python\chromedriver.exe"
#获取数据
self.lable=[]
self.tip=[]
self.content=[]
self.image_f=[]
self.image_s=[]
self.time=[]
  1. 访问页面

  headless赋值为True是开启无头模式测试,初次使用webdriver自动化测试的小伙伴可以去掉这行体验一下

option=webdriver.ChromeOptions()
option.headless=True
option.binary_location=r'D:\Google\Chrome\Application\chrome.exe'
self.driver = webdriver.Chrome(executable_path=self.driver_path,options=option)
self.driver.get(self.url)
time.sleep(10)#这里也可以使用self.driver.implicitly_wait(10) 

  implicitly_wait(10) 隐性等待的好处是在设定的时间内只要加载完毕就执行下一步,不用像time.sleep那样强行等待10秒钟

  1. 获取文本数据
# 获取lable
wash=self.driver.find_elements_by_tag_name('h3')
metri.wash_data(wash,0)#wash_data()调用函数对获取到的数据进行清洗
#获取tip
wash=self.driver.find_elements_by_class_name('tip')
wash.pop(0)
metri.wash_data(wash,2)
#获取content
wash=self.driver.find_elements_by_tag_name('dd')
metri.wash_data(wash,1)

  metri是使用类class的名称:metri=metrics(),由于网页设计的原因有时开发人员的无规律设计可能导致我们获取的数据与期望存在偏差,小问题清洗一下就好了

  1. 获取折线图

  对于这类难获取,获取后难以可视化的情形(如下图),博主非常推荐使用selenium中screenshoot_as_png按元素定位拍照的方法
History折线图

  一筹莫展的时候正好发现了screenshoot的功能,可谓是柳暗花明又一村

self.image_f.append(self.driver.find_element_by_xpath('//*[@id="bw_month"]').screenshot_as_png)
self.image_s.append(self.driver.find_element_by_xpath('//*[@id="weights_month"]').screenshot_as_png)
self.time.append(self.driver.find_element_by_id('history-1m-tab').text)

Mysql数据库

   Mariadb和Oracle甲骨文旗下的Mysql之间的渊源,感兴趣的小伙伴可以去了解一下,Mariadb由于是开源的软件所以更新迭代的次数要比Mysql多,但是两者的语法和大体功能上是相同的

  1. 初始化信息

  在开始运行前一定要安装配置好mysql,我这里使用的是mariadb附上下载链接https://mariadb.com/downloads/,登录界面长这样
Mariadb

  mysql登录信息

    def __init__(self):# mysql登录信息self.host='127.0.0.1'self.user='root'self.password='123456'self.chartset='utf8'#编码格式注意这里不是utf-8,数据库这里的参数配置没有'-'self.database='metrics_db'#数据库名称
  1. 建立数据库
 def set_sqldb(self,sql):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,)cursor=db.cursor()try:cursor.execute("create database metrics_db character set utf8;")except:passcursor.close()db.close()
  1. 建立数据表
    #建立mysql数据表def set_sqlist(self,sql,list_lable):db=sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql="""drop table if exists `%s`"""%((list_lable))cursor.execute(sql)if list_lable=='History':sql = """create table if not  exists `%s`(id int auto_increment primary key comment'序列号',time VARCHAR(255) not null comment '月份',graph1 longblob comment '图片',graph2 longblob comment '图片');""" % (list_lable)else:sql="""create table if not  exists `%s`(id int auto_increment primary key comment'序列号',item VARCHAR(255) not null comment '项目名称',value VARCHAR(255) not null comment '内容',notes VARCHAR(255) not null comment '备注');"""%(list_lable)cursor.execute(sql)cursor.close()db.close()

  这里博主建表个数是依据爬取页面lable的个数,故在命名时要使用变量建表,格式为代码中sql=“”" “”"三双引号内的部分,这里就不得不吐槽一下python里引号类型是真的多(单引号,双引号,三引号,三双引号)一不留神就用错了

数据库中导入数据

  1. 插入文本数据
 # 添加文本数据def insert_txt_sqldb(self,sql,list_lable,st1,st2):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql = """insert into `%s`(item,value,notes)values ('%s','%s','%s')""" % ((list_lable), st1, st2, 'null')try:# 执行sql语句cursor.execute(sql)# 数据库执行sql语句db.commit()except Exception as res:# 发生错误时回滚db.rollback()print("error %s" % res)cursor.close()db.close()
  1. 插入图片数据
 def insert_picture_sqldb(self,sql,list_lable):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql="insert into History(time,graph1,graph2)values(%s,%s,%s);"for i in range(len(self.time)):try:# 执行sql语句cursor.execute(sql,[self.time[i],self.image_f[i],self.image_s[i]])# 数据库执行sql语句db.commit()except Exception as res:# 发生错误时回滚db.rollback()print("error %s" % res)cursor.close()db.close()

  相信细心的小伙伴已经发现了,之前在建表的时候sql语句中分了两种格式,如下,graph1列对应的数据是longblob,blob是二进制数据类型,在数据库中有blob,mediumblob以及longblob,区别就在于存储数据的大小,插入指令为sql=“insert into History(time,graph1,graph2)values(%s,%s,%s);”,cursor.execute(sql,[self.time[i],self.image_f[i],self.image_s[i]])同样表明为变量插入时格式也为变量形式

sql = """create table if not  exists `%s`(id int auto_increment primary key comment'序列号',time VARCHAR(255) not null comment '月份',graph1 longblob comment '图片',graph2 longblob comment '图片');""" % (list_lable)

结果展示(一)

Configuration标签数据
Configuration标签数据
Properties标签数据
Properties标签数据
History折线图数据
History折线图数据
当然二进制形式不方便查看,我们再从Mysql中将数据提取出保存为本地文件

图片本地存储

    def extract_picture(self,sql):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor = db.cursor()cursor.execute('select graph1 from History')out_1=cursor.fetchall()cursor.execute('select graph2 from History')out_2=cursor.fetchall()for i in range(4):with open('pair'+str(i+1)+'_graph_1.png',mode="wb")as f1:f1.write(out_1[i][0])f1.close()time.sleep(random.uniform(2, 3))with open('pair'+str(i+1)+'_graph_2.png',mode="wb")as f2:f2.write(out_2[i][0])f2.close()time.sleep(random.uniform(2, 3))cursor.close()db.close()

结果展示(二)

History折线图片数据本地保存效果

History折线图片数据本地保存

附上代码

感谢大家的驻足,最后附上代码,有什么问题欢迎评论区留言,下期见!

from selenium import webdriver
import pymysql as sql
import time
import randomclass metrics(object):# 初始化信息def __init__(self):# mysql登录信息self.host='127.0.0.1'self.user='root'self.password='123456'self.chartset='utf8'self.database='metrics_db'#webdriver初始化self.url="https://metrics.torproject.org/rs.html#details/0E300A0942899B995AE08CEF58062BCFEB51EEDF"self.driver_path=r"D:\python\chromedriver.exe"#获取数据self.lable=[]self.tip=[]self.content=[]self.image_f=[]self.image_s=[]self.time=[]#建立数据库def set_sqldb(self,sql):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,)cursor=db.cursor()try:cursor.execute("create database metrics_db character set utf8;")except:passcursor.close()db.close()#建立mysql数据表def set_sqlist(self,sql,list_lable):db=sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql="""drop table if exists `%s`"""%((list_lable))cursor.execute(sql)if list_lable=='History':sql = """create table if not  exists `%s`(id int auto_increment primary key comment'序列号',time VARCHAR(255) not null comment '月份',graph1 longblob comment '图片',graph2 longblob comment '图片');""" % (list_lable)else:sql="""create table if not  exists `%s`(id int auto_increment primary key comment'序列号',item VARCHAR(255) not null comment '项目名称',value VARCHAR(255) not null comment '内容',notes VARCHAR(255) not null comment '备注');"""%(list_lable)cursor.execute(sql)cursor.close()db.close()# 数据转换清洗def wash_data(self,wash,flag):if flag==0:for i in range(len(wash)):self.lable.append(wash[i].text)a=0if flag==1:for i in range(len(wash)):if(wash[i].text)=='':a+=1if a==2:continueself.content.append(wash[i].text)b=0if flag==2:for i in range(len(wash)):if(b==0):self.tip.append(wash[i].text)if(b!=0):b-=1if wash[i].text=='Flags':b=3if wash[i].text=='Advertised Bandwidth':b=1# 添加图片数据def insert_picture_sqldb(self,sql,list_lable):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql="insert into History(time,graph1,graph2)values(%s,%s,%s);"for i in range(len(self.time)):try:# 执行sql语句cursor.execute(sql,[self.time[i],self.image_f[i],self.image_s[i]])# 数据库执行sql语句db.commit()except Exception as res:# 发生错误时回滚db.rollback()print("error %s" % res)cursor.close()db.close()#访问网页def website_get(self):option=webdriver.ChromeOptions()option.headless=Trueoption.binary_location=r'D:\Google\Chrome\Application\chrome.exe'self.driver = webdriver.Chrome(executable_path=self.driver_path,options=option)self.driver.get(self.url)time.sleep(10)# 获取lablewash=self.driver.find_elements_by_tag_name('h3')metri.wash_data(wash,0)#获取tipwash=self.driver.find_elements_by_class_name('tip')wash.pop(0)metri.wash_data(wash,2)#获取contentwash=self.driver.find_elements_by_tag_name('dd')metri.wash_data(wash,1)#获取image曲线图self.image_f.append(self.driver.find_element_by_xpath('//*[@id="bw_month"]').screenshot_as_png)self.image_s.append(self.driver.find_element_by_xpath('//*[@id="weights_month"]').screenshot_as_png)self.time.append(self.driver.find_element_by_id('history-1m-tab').text)self.driver.find_element_by_id('history-6m-tab').click()self.image_f.append(self.driver.find_element_by_xpath('//*[@id="bw_months"]').screenshot_as_png)self.image_s.append(self.driver.find_element_by_xpath('//*[@id="weights_months"]').screenshot_as_png)self.time.append(self.driver.find_element_by_id('history-6m-tab').text)self.driver.find_element_by_id('history-1y-tab').click()self.image_f.append(self.driver.find_element_by_xpath('//*[@id="bw_year"]').screenshot_as_png)self.image_s.append(self.driver.find_element_by_xpath('//*[@id="weights_year"]').screenshot_as_png)self.time.append(self.driver.find_element_by_id('history-1y-tab').text)self.driver.find_element_by_id('history-5y-tab').click()self.image_f.append(self.driver.find_element_by_xpath('//*[@id="bw_years"]').screenshot_as_png)self.image_s.append(self.driver.find_element_by_xpath('//*[@id="weights_years"]').screenshot_as_png)self.time.append(self.driver.find_element_by_id('history-5y-tab').text)# 添加文本数据def insert_txt_sqldb(self,sql,list_lable,st1,st2):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor=db.cursor()sql = """insert into `%s`(item,value,notes)values ('%s','%s','%s')""" % ((list_lable), st1, st2, 'null')try:# 执行sql语句cursor.execute(sql)# 数据库执行sql语句db.commit()except Exception as res:# 发生错误时回滚db.rollback()print("error %s" % res)cursor.close()db.close()# 本地存储图片数据def extract_picture(self,sql):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor = db.cursor()cursor.execute('select graph1 from History')out_1=cursor.fetchall()cursor.execute('select graph2 from History')out_2=cursor.fetchall()for i in range(4):with open('pair'+str(i+1)+'_graph_1.png',mode="wb")as f1:f1.write(out_1[i][0])f1.close()time.sleep(random.uniform(2, 3))with open('pair'+str(i+1)+'_graph_2.png',mode="wb")as f2:f2.write(out_2[i][0])f2.close()time.sleep(random.uniform(2, 3))cursor.close()db.close()# 存入txt文件def save(self):db = sql.connect(host=self.host,user=self.user,password=self.password,charset=self.chartset,database=self.database)cursor = db.cursor()cursor.execute('select * from Configuration')out_put = cursor.fetchall()for a in out_put:with open('metrics_1.txt','a') as f:f.write(str(a)+'\n')f.close()cursor.execute('select * from Properties')out_put2 = cursor.fetchall()for a in out_put2:with open('metrics_2.txt', 'a') as f:f.write(str(a) + '\n')f.close()cursor.close()db.close()if __name__=="__main__":metri=metrics()metri.set_sqldb(sql)metri.website_get()for i in range(len(metri.lable)):metri.set_sqlist(sql,metri.lable[i])# 表1for i in range(11):metri.insert_txt_sqldb(sql,metri.lable[0],metri.tip[i],metri.content[i])# 表2for i in range(11,len(metri.content)):metri.insert_txt_sqldb(sql,metri.lable[1],metri.tip[i],metri.content[i])# 表3metri.insert_picture_sqldb(sql,metri.lable[2])#提取sql图片数据并本地保存metri.extract_picture(sql)#提取所有数据保存到txt文件metri.save()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/64042.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自学 AI 一年的体会(1):谈技术书籍出版的长长短短

自学AI近一年,发现打开了一片新的技术大门,不再局限于漏洞攻防这块地盘,更关键是AI可以应用于诸多领域,甚至已不局限于计算机领域了,能搞的事情更多了。在此期间,自己也使用NLP自然语言处理技术开发出多个模…

自学大语言模型之GPT

GPT火爆的发展史 2017年6月OpenAI联合DeepMind首次正式提出的:Deep Reinforcement Learning from Human Preferences,即基于人类偏好的深度强化学习,简称RLHF 2017年7月的OpenAI团队提出的对TRPO算法的改进:PPO算法 GPT-1&#…

考研党福利?ChatGPT秒杀了所有408考研编程题……

来源:新智元 本文均由ChatGPT生成 那么,ChatGPT可以解决408中的编程题吗? 直接结论:由ChatGPT给出的408代码90%可以拿满分 2023年408的编程题 哟,看着还行 2022年408编程题 解答题回答的也不错 2021年408编程题 ChatGP…

chatgpt赋能python:Python编程题怎么搜答案

Python编程题怎么搜答案 Python是一种高级编程语言,具有易读性、简洁性和可重用性等优点,因此越来越多的程序员选择使用Python开发应用程序。但是在面对Python编程题的时候,即使你已经有了10年的编程经验,可能也会遇到一些问题。…

利用ChatGPT学习编程,让你成为新时代程序员

大家好,我是静幽水,目前是一名大厂全栈工程师,擅长Java后端,Vue前端,小程序编程,Python编程,ChatGPT 提示词等技术。我会分享一些相关的干货知识,感兴趣的话就关注我吧,希…

活学活用虚拟环境,Python编程更高效

介绍4种在Python中使用虚拟环境的方法。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 本文将涵盖以下主题:什么是python中的虚拟环境?为什么需要虚拟环境?在Python中设置虚拟环境的4种不同方法。本文将…

用好这两个方法,解决Python中的线程同步问题

了解互斥锁和连接,实现Python中安全有效的多线程。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 同步的重要性是什么? 假设有一个共享的家庭银行账户,余额为50美元,属于你和你父亲。 爸爸挣…

了解Python编码风格,让你的代码更好看

和其他编程语言不同,Python有一套独特的编码风格,掌握Python的编码风格对于编写优美的代码至关重要。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 本文是一篇快速了解Python编码风格的指南,了解Python…

国家电网可视化平台完工交付给客户!

国家电网可视化平台完工交付给客户,助力电网信息化! 转载于:https://www.cnblogs.com/shuzikeji/p/7844358.html

2019年南方电网和国家电网考纲对比(通信类)

最近在准备关于国家电网和南方电网的校园招聘笔试,整理了如上内容,仅供参考,小结如下: 南方电网: 批次:南方电网校园招聘考试一般每年只有一批,比重:比较注重面试环节,面…

国家电网 计算机 《信息新技术》 整理

信息新技术概论 分布式处理基础分布式数据库(DDB,Distributed Database)︰分布式文件系统(DFS,Distributed File System)区块链(Blockchain): 物联网基础基本概念 大数据基础人工智能基础神经网络(NNsNeural Networks)机器学习 典型硬件技术基…

【NLP】千呼万唤始出来——GPT-3终于开源!

文 | 小戏编 | 小轶 GPT3终于开源!不过,不是官方开的(别打我 Eleuther AI推出的名为GPT-Neo的开源项目,于今晨4点于twitter正式宣布:已经开源了复现版GPT-3的模型参数(1.3B和2.7B级别)&#xff…

属于自己的贾维斯

属于自己的贾维斯之Python学习 人生第一次写博客,想记录下自己的学习过程,以便以后复习简单(毕竟自己的博客总想知道有没有人来看,就可以顺便过来复习了),因为用笔的记录感觉都没怎么去看,所以就想用这种方法来记录。因为本人比较懒再加上精神…

七夕送女友什么礼物有意义、送女朋友实用的七夕礼物清单

在即将到来的中国传统情人节——七夕节当中,怎样送女朋友实用又用心的礼物呢?想必有不少男生朋友们不知道怎么选择吧!要知道合适的礼物可以在改善生活质量的同时也为彼此的感情带来惊喜,今天就为大家带来送女朋友实用的5个礼物推荐…

七夕节送女朋友什么礼物、能让女生感动到哭的礼物推荐

七夕作为我国的传统情人节马上就要到来了。在这一天也是恋爱中人相互向对方表达爱意的好时机,精心为对方准备一份七夕礼物也是情理之中的事,但是咱们很多男性小伙伴在面对市面上令人眼花缭乱礼物的时候,在挑选问题上却是不知从何下手了。别担…

程序员如何哄女朋友开心的秘籍,定制给女朋友一个应用(生日礼物)

这算是我写的安卓比较完整的一个应用了吧,不过其实也还不怎么完整,还有好多功能没有加进去,但是由于昨天是女朋友的生日,所以就送给他了,这也是我学习安卓半个月来的第一个应用了“音乐播放器”! 制作&…

女朋友过生日送什么礼物好?

观察她喜欢什么 平日里陪她逛街购物时,你留意到她很喜欢一件衣服或是饰品之类的,她可能因为各种原因,没买。你记在心里面,生日前买下了,作为生日礼物送个她,她会非常的欢喜。 如果离过生日还有很长一段时间…

如何做一个网页送给女朋友做生日礼物!感动到哭!

如何做一个网页送给女朋友做生日礼物 本文里面涉及到python,HTML ,css,JavaScript的知识,是基于python的flask框架做的一个小型网站,里面可以实现跳转功能,怎么配置flask的环境变量,去官方文档看就好了&am…

情人节送女朋友什么礼物最好?五大首选礼物排行榜单!

一年一度的情人节又要到了,各位男生有没有因为不知道给女朋友们挑选什么礼物而心慌慌?情人节礼物绝对能反映出你对女朋友平时喜好的了解程度,选对了情人节礼物,可以让你们的感情更加甜蜜。今天就来说说有哪几款非常适合送女孩子的…

如何做一个网页送给女朋友做生日礼物!这应该是最好的礼物了!

如何做一个网页送给女朋友做生日礼物 本文里面涉及到python,HTML ,css,JavaScript的知识,是基于python的flask框架做的一个小型网站,里面可以实现跳转功能,怎么配置flask的环境变量,去官方文档看就好了&am…