python Selenium爬取内容并存储至MySQL数据库的实现代码


Posted in Python onMarch 16, 2017

前面我通过一篇文章讲述了如何爬取CSDN的博客摘要等信息。通常,在使用Selenium爬虫爬取数据后,需要存储在TXT文本中,但是这是很难进行数据处理和数据分析的。这篇文章主要讲述通过Selenium爬取我的个人博客信息,然后存储在数据库MySQL中,以便对数据进行分析,比如分析哪个时间段发表的博客多、结合WordCloud分析文章的主题、文章阅读量排名等。
这是一篇基础性的文章,希望对您有所帮助,如果文章中出现错误或不足之处,还请海涵。下一篇文章会简单讲解数据分析的过程。

一. 爬取的结果
爬取的地址为:http://blog.csdn.net/Eastmount

python Selenium爬取内容并存储至MySQL数据库的实现代码

        

        爬取并存储至MySQL数据库的结果如下所示:

python Selenium爬取内容并存储至MySQL数据库的实现代码

        运行过程如下图所示:

python Selenium爬取内容并存储至MySQL数据库的实现代码

二. 完整代码分析

完整代码如下所示:

# coding=utf-8 
 
from selenium import webdriver 
from selenium.webdriver.common.keys import Keys 
import selenium.webdriver.support.ui as ui   
import re
import time
import os
import codecs
import MySQLdb
 
#打开Firefox浏览器 设定等待加载时间 
driver = webdriver.Firefox()
wait = ui.WebDriverWait(driver,10) 

#获取每个博主的博客页面低端总页码  
def getPage():
 print 'getPage'
 number = 0  
 texts = driver.find_element_by_xpath("//div[@id='papelist']").text  
 print '页码', texts  
 m = re.findall(r'(\w*[0-9]+)\w*',texts) #正则表达式寻找数字  
 print '页数:' + str(m[1])  
 return int(m[1]) 
 
#主函数 
def main():
 #获取txt文件总行数
 count = len(open("Blog_URL.txt",'rU').readlines())
 print count
 n = 0
 urlfile = open("Blog_URL.txt",'r')

 #循环获取每个博主的文章摘信息 
 while n < count: #这里爬取2个人博客信息,正常情况count个博主信息
  url = urlfile.readline()
  url = url.strip("\n")
  print url
  driver.get(url)
  #获取总页码
  allPage = getPage()
  print u'页码总数为:', allPage
  time.sleep(2)

  #数据库操作结合
  try:
   conn=MySQLdb.connect(host='localhost',user='root',
         passwd='123456',port=3306, db='test01')
   cur=conn.cursor() #数据库游标

   #报错:UnicodeEncodeError: 'latin-1' codec can't encode character
   conn.set_character_set('utf8')
   cur.execute('SET NAMES utf8;')
   cur.execute('SET CHARACTER SET utf8;')
   cur.execute('SET character_set_connection=utf8;')
   
   #具体内容处理
   m = 1 #第1页
   while m <= allPage:
    ur = url + "/article/list/" + str(m)
    print ur
    driver.get(ur)
    
    #标题
    article_title = driver.find_elements_by_xpath("//div[@class='article_title']")
    for title in article_title:
     #print url
     con = title.text
     con = con.strip("\n")
     #print con + '\n'
    
    #摘要
    article_description = driver.find_elements_by_xpath("//div[@class='article_description']")
    for description in article_description:
     con = description.text
     con = con.strip("\n")
     #print con + '\n'

    #信息
    article_manage = driver.find_elements_by_xpath("//div[@class='article_manage']")
    for manage in article_manage:
     con = manage.text
     con = con.strip("\n")
     #print con + '\n'

    num = 0
    print u'长度', len(article_title)
    while num < len(article_title):
     #插入数据 8个值
     sql = '''insert into csdn_blog
        (URL,Author,Artitle,Description,Manage,FBTime,YDNum,PLNum)
       values(%s, %s, %s, %s, %s, %s, %s, %s)'''
     Artitle = article_title[num].text
     Description = article_description[num].text
     Manage = article_manage[num].text
     print Artitle
     print Description
     print Manage
     #获取作者
     Author = url.split('/')[-1]
     #获取阅读数和评论数
     mode = re.compile(r'\d+\.?\d*')
     YDNum = mode.findall(Manage)[-2]
     PLNum = mode.findall(Manage)[-1]
     print YDNum
     print PLNum
     #获取发布时间
     end = Manage.find(u' 阅读')
     FBTime = Manage[:end]
     cur.execute(sql, (url, Author, Artitle, Description, Manage,FBTime,YDNum,PLNum)) 
     
     num = num + 1
    else:
     print u'数据库插入成功'    
    m = m + 1
     
  
  #异常处理
  except MySQLdb.Error,e:
   print "Mysql Error %d: %s" % (e.args[0], e.args[1])
  finally:
   cur.close() 
   conn.commit() 
   conn.close()
  
  n = n + 1
    
 else:
  urlfile.close()
  print 'Load Over'
   
main()

在Blog_Url.txt文件中放置需要爬取用户的博客地址URL,如下图所示。注意在此处,作者预先写了个爬取CSDN所有专家的URL代码,这里为访问其他人用于提升阅读量已省略。

python Selenium爬取内容并存储至MySQL数据库的实现代码

分析过程如下所示。
1.获取博主总页码
首先从Blog_Url.txt读取博主地址,然后访问并获取页码总数。代码如下:

#获取每个博主的博客页面低端总页码  
def getPage():
 print 'getPage'
 number = 0  
 texts = driver.find_element_by_xpath("//div[@id='papelist']").text  
 print '页码', texts  
 m = re.findall(r'(\w*[0-9]+)\w*',texts) #正则表达式寻找数字  
 print '页数:' + str(m[1])  
 return int(m[1])

比如获取总页码位17页,如下图所示:

python Selenium爬取内容并存储至MySQL数据库的实现代码

2.翻页DOM树分析
这里的博客翻页采用的是URL连接,比较方便。
如:http://blog.csdn.net/Eastmount/article/list/2
故只需要 :1.获取总页码;2.爬取每页信息;3.URL设置进行循环翻页;4.再爬取。
也可以采用点击"下页"跳转,没有"下页"停止跳转,爬虫结束,接着爬取下一个博主。

python Selenium爬取内容并存储至MySQL数据库的实现代码

3.获取详细信息:标题、摘要、时间
然后审查元素分析每个博客页面,如果采用BeautifulSoup爬取会报错"Forbidden"。
发现每篇文章都是由一个<div></div>组成,如下所示,只需要定位到该位置即可。

python Selenium爬取内容并存储至MySQL数据库的实现代码

        这里定位到该位置即可爬取,这里需要分别定位标题、摘要、时间。

python Selenium爬取内容并存储至MySQL数据库的实现代码

代码如下所示。注意,在while中同时获取三个值,它们是对应的。

#标题
article_title = driver.find_elements_by_xpath("//div[@class='article_title']")
for title in article_title:
 con = title.text
 con = con.strip("\n")
 print con + '\n'
    
#摘要
article_description = driver.find_elements_by_xpath("//div[@class='article_description']")
for description in article_description:
 con = description.text
 con = con.strip("\n")
 print con + '\n'

#信息
article_manage = driver.find_elements_by_xpath("//div[@class='article_manage']")
for manage in article_manage:
 con = manage.text
 con = con.strip("\n")
 print con + '\n'

num = 0
print u'长度', len(article_title)
while num < len(article_title):
 Artitle = article_title[num].text
 Description = article_description[num].text
 Manage = article_manage[num].text
 print Artitle, Description, Manage

 4.特殊字符串处理
获取URL最后一个/后的博主名称、获取字符串时间、阅读数代码如下:

#获取博主姓名
url = "http://blog.csdn.net/Eastmount"
print url.split('/')[-1]
#输出: Eastmount

#获取数字
name = "2015-09-08 18:06 阅读(909) 评论(0)"
print name
import re
mode = re.compile(r'\d+\.?\d*') 
print mode.findall(name)
#输出: ['2015', '09', '08', '18', '06', '909', '0']
print mode.findall(name)[-2]
#输出: 909


#获取时间
end = name.find(r' 阅读')
print name[:end]
#输出: 2015-09-08 18:06

import time, datetime
a = time.strptime(name[:end],'%Y-%m-%d %H:%M')
print a
#输出: time.struct_time(tm_year=2015, tm_mon=9, tm_mday=8, tm_hour=18, tm_min=6,
#  tm_sec=0, tm_wday=1, tm_yday=251, tm_isdst=-1)

三. 数据库相关操作
SQL语句创建表代码如下:

CREATE TABLE `csdn` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `URL` varchar(100) COLLATE utf8_bin DEFAULT NULL,
 `Author` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '作者',
 `Artitle` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '标题',
 `Description` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '摘要',
 `Manage` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '信息',
 `FBTime` datetime DEFAULT NULL COMMENT '发布日期',
 `YDNum` int(11) DEFAULT NULL COMMENT '阅读数',
 `PLNum` int(11) DEFAULT NULL COMMENT '评论数',
 `DZNum` int(11) DEFAULT NULL COMMENT '点赞数',
 PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9371 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

显示如下图所示:

python Selenium爬取内容并存储至MySQL数据库的实现代码

其中,Python调用MySQL推荐下面这篇文字。
python专题九.Mysql数据库编程基础知识
核心代码如下所示:

# coding:utf-8 
import MySQLdb
 
try:
 conn=MySQLdb.connect(host='localhost',user='root',passwd='123456',port=3306, db='test01')
 cur=conn.cursor()
 
 #插入数据
 sql = '''insert into student values(%s, %s, %s)'''
 cur.execute(sql, ('yxz','111111', '10'))

 #查看数据
 print u'\n插入数据:'
 cur.execute('select * from student')
 for data in cur.fetchall():
  print '%s %s %s' % data
 cur.close()
 conn.commit()
 conn.close()
except MySQLdb.Error,e:
  print "Mysql Error %d: %s" % (e.args[0], e.args[1])

注意,在下载过程中,有的网站是新版本的,无法获取页码。
比如:http://blog.csdn.net/michaelzhou224
这时需要简单设置,跳过这些链接,并保存到文件中,核心代码如下所示:

#获取每个博主的博客页面低端总页码  
def getPage():
 print 'getPage'
 number = 0  
 #texts = driver.find_element_by_xpath("//div[@id='papelist']").text
 texts = driver.find_element_by_xpath("//div[@class='pagelist']").text
 print 'testsss'
 print u'页码', texts
 if texts=="":
  print u'页码为0 网站错误'
  return 0
 m = re.findall(r'(\w*[0-9]+)\w*',texts) #正则表达式寻找数字  
 print u'页数:' + str(m[1])  
 return int(m[1])

主函数修改:

error = codecs.open("Blog_Error.txt", 'a', 'utf-8')

 #循环获取每个博主的文章摘信息 
 while n < count: #这里爬取2个人博客信息,正常情况count个博主信息
  url = urlfile.readline()
  url = url.strip("\n")
  print url
  driver.get(url+"/article/list/1")
  #print driver.page_source
  #获取总页码
  allPage = getPage()
  print u'页码总数为:', allPage
  #返回错误,否则程序总截住
  if allPage==0:
   error.write(url + "\r\n")
   print u'错误URL'
   continue; #跳过进入下一个博主
  time.sleep(2)
  #数据库操作结合
  try:
    .....

最后希望文章对你有所帮助,如果文章中存在错误或不足之处,还请海涵~
提高效率,提升科研,认真教学,娜美人生。

Python 相关文章推荐
python实现html转ubb代码(html2ubb)
Jul 03 Python
python中日期和时间格式化输出的方法小结
Mar 19 Python
Python多线程编程(一):threading模块综述
Apr 05 Python
Python中用PIL库批量给图片加上序号的教程
May 06 Python
深入解析Python中的WSGI接口
May 11 Python
用python结合jieba和wordcloud实现词云效果
Sep 05 Python
使用python制作一个为hex文件增加版本号的脚本实例
Jun 12 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
Apr 12 Python
利用python实现平稳时间序列的建模方式
Jun 03 Python
使用Keras训练好的.h5模型来测试一个实例
Jul 06 Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 Python
Python 解决空列表.append() 输出为None的问题
May 23 Python
python开发利器之ulipad的使用实践
Mar 16 #Python
离线安装Pyecharts的步骤以及依赖包流程
Apr 23 #Python
Python中%r和%s的详解及区别
Mar 16 #Python
Python 装饰器深入理解
Mar 16 #Python
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
Mar 16 #Python
Django卸载之后重新安装的方法
Mar 15 #Python
Python json 错误xx is not JSON serializable解决办法
Mar 15 #Python
You might like
轻松入门: 煮好咖啡的七个诀窍
2021/03/03 冲泡冲煮
PHP 高级课程笔记 面向对象
2009/06/21 PHP
PHP操作Memcache实例介绍
2013/06/14 PHP
php生成扇形比例图实例
2013/11/06 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
PHP内存缓存功能memcached示例
2016/10/19 PHP
IE与FireFox中的childNodes区别
2011/10/20 Javascript
jquery获取自定义属性(attr和prop)实例介绍
2013/04/21 Javascript
nodejs开发微博实例
2015/03/25 NodeJs
javascript实现Table排序的方法
2015/05/15 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
jQuery+css实现的切换图片功能代码
2016/01/27 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
jquery,js简单实现类似Angular.js双向绑定
2017/01/13 Javascript
前端自动化开发之Node.js的环境搭建教程
2017/04/01 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
vue-froala-wysiwyg 富文本编辑器功能
2019/09/19 Javascript
编写Python CGI脚本的教程
2015/06/29 Python
教大家使用Python SqlAlchemy
2016/02/12 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
python 用lambda函数替换for循环的方法
2018/06/09 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
在PyCharm导航区中打开多个Project的关闭方法
2019/01/17 Python
python代码 FTP备份交换机配置脚本实例解析
2019/08/01 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
Python编程快速上手——正则表达式查找功能案例分析
2020/02/28 Python
Python3实现个位数字和十位数字对调, 其乘积不变
2020/05/03 Python
Python爬虫之爬取淘女郎照片示例详解
2020/07/28 Python
深入理解css中vertical-align属性
2017/04/18 HTML / CSS
kfc实习自我鉴定
2013/12/14 职场文书
父亲生日宴会答谢词
2014/01/10 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
积极向上的团队口号
2014/06/06 职场文书