1 #coding:utf-8

2 importrequests3 from bs4 importBeautifulSoup4 importMySQLdb5

6

7 defget_html(url):8 '''

9 获取页面HTML源码,并返回10 '''

11 html =requests.get(url)12 content = html.text.encode('utf-8')13 returncontent14

15 defget_blog_html_list(html_content):16 globaladdr17 '''

18 在HTML源码中获取到blog相关的值,并返回19 '''

20 bs = BeautifulSoup(html_content,'lxml')21 #此处的class要加上下划线,否则会和系统内预定的class冲突

22 blog_list = bs.find_all('div', class_ = 'entrylistItem')23 for i inrange(len(blog_list)):24 sub_dict ={}25 sub_dict['title'] =blog_list[i].a.get_text()26 sub_dict['link'] = blog_list[i].a.get('href')27 sub_dict['abstract'] =blog_list[i].div.get_text()28 insert_to_db(sub_dict)29 returnsub_dict30

31 def insert_to_db(dict={} ):32 conn = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '12345a',33 db = 'pytest01', charset = 'utf8')34 cur =conn.cursor()35

36 try:37 cur.execute('insert into blog_details (title, link, abstract) values (%s, %s, %s)',38 (dict['title'], dict['link'], dict['abstract']))39 exceptMySQLdb.Error, e:40 pass

41 conn.commit()42 cur.close()43 conn.close()

1 #coding:utf-8

2 importurllib3 importrequests4 from bs4 importBeautifulSoup5 importMySQLdb6 importCrawler.get_file7 from docx importDocument8 importtime9 import docx.image #超链接图片抛出的异常在docx.image中

10

11 index = '0'

12

13 defget_blog_pic(pic_url, index):14 print 'download picture'

15 '''

16 下载指定URL的图片,并且以index命名保存到temp_pic 文件夹内17 '''

18 path = 'D:\\workspace_Java\\cnBlogCrawler\\temp_pic\\' + index + '.png'

19 try:20 pic =urllib.urlretrieve(pic_url, path)21 exceptAttributeError,e:22 path = r'C:\Users\Lisen\Desktop\error.jpg'

23 print 'download picture error, the link is' +pic_url24 pass

25 finally:26 returnpath27

28 defget_blog_body(url, title):29 print 'download blog'

30 print title, time.strftime('%Y-%m-%d %H:%M:%S')31 file_path = 'D:\\workspace_Java\\cnBlogCrawler\\temp_doc\\' + title + '.docx'

32 header = {'Accept':'text/html,application/xhtml+xml,application/xml',33 'Accept-Encoding':'gzip, deflate, sdch',34 'Accept-Language':'zh-CN,zh;q=0.8',35 'Cache-Control':'max-age=0',36 'Connection':'keep-alive',37 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36'}38 html =requests.get(url,header).text39 bs = BeautifulSoup(html, 'lxml')40 print 'html ready'

41 '''

42 获取html中blog正文部分43 '''

44 body = bs.find_all('p')45 '''

46 创建文档47 '''

48 doc =Document()49 for each inbody:50 #在函数中改变全局变量需要用global声明下

51 globalindex52 '''

53 如果p节点有子节点a的话,就说明其中是带着图片的链接或者是文本本身就是链接,因此要分三种情况去爬取54 1. 没有子节点:直接获取text部分55 2. 有子节点 a, 但是该子节点没有text部分,说明这是图片56 3. 有子节点a, 且该子节点有text部分,则里面是文本57 '''

58 if each.a !=None:59 txt =each.a.get_text()60 if txt == '':61 print 'pic'

62 url = each.a.get('href')63 index = str(int(index) + 1)64 pic_name =get_blog_pic(url, index)65 try:66 doc.add_picture(pic_name)67 exceptdocx.image.exceptions.UnrecognizedImageError, e:68 pass

69 else:70 print 'URL'

71 content =each.a.get_text()72 paragraph =doc.add_paragraph(content)73 else:74 print 'txt'

75 content =each.get_text()76 paragraph =doc.add_paragraph(content)77 try:78 print 'saving file'

79 doc.save(file_path)80 exceptIOError,e:81 print 'file saving error'

82 print 'error url is' +url83 pass

1 importMySQLdb2 importCrawler.get_file3 importCrawler.get_blog_details4 importtime5

6 if __name__ == '__main__':7

8 conn = MySQLdb.connect(host = 'localhost', user = 'root', passwd = '12345a',9 db = 'pytest01', charset = 'utf8')10 cur =conn.cursor()11 cur.execute('truncate blog_details')12 url = r'http://www.cnblogs.com/omygod/category/460309.html'

13 print 'next parsing html'

14 html =Crawler.get_blog_details.get_html(url)15 print 'next parsing blog address'

16 dict =Crawler.get_blog_details.get_blog_html_list(html)17 print 'next update MySQL'

18 Crawler.get_blog_details.insert_to_db(dict)19

20 cur.execute('select * from blog_details')21 lines =cur.fetchall()22 for line inlines:23 Crawler.get_file.get_blog_body(line[1],line[0])24 print 'done' + time.strftime('%Y-%m-%d %H:%M:%S')25 time.sleep(2)26 print 'wait over'

27 cur.close()28 conn.close()

由于博客园的原创博客都是通过随笔的形式保存的,因此我们可以通过对某一随笔目录进行解析,获取出该目录下所有博文的标题,链接以及摘要,存储到MySQL数据库中(主要是因为可以持久记录相关信息,后续有新博文的时候可以通过对比判断直接下载新的博文)。然后再对每个条目进行单独解析,将博文的内容,图片保存到Word文档中。

主要用到的包有: requests, BeautifulSoup,python-docx, MySQLdb

requests和BeautifulSoup主要是用来获取网页源代码以及对其进行解析;

MySQLdb是用来通过Python操控MySQL数据库, 具体可参照SegmentFault中的一篇文章:https://segmentfault.com/a/1190000000709735

整个代码分为三部分:

第一部分是get_blog_details.py,主要是获取目录下各个博文的详细信息,并存到MySQL数据库中

第二部分是get_file.py,获取各个博文的地址等并生成Word文档

第三部分是__init__.py, 程序开始

在编写代码过程中,有几个地方需要注意:

若在函数中改变全局变量,需要在函数中声明: global g_var

在用BeautifulSoup解析某个节点的class属性是,不能直接用class否则会报错,因为class是保留关键字, 要在class后加_, 如:blog_list = bs.find_all('div', class_ = 'entrylistItem')

在py文件中import其他py文件时,一要在文件目录中添加 __init__.py 文件,二是要在导入是加上对应文件夹的名字,如:import Crawler.get_file

现阶段缺点:

程序运行速度慢,后期准备学习下多线程爬虫

Word文档中图片太大以至于不方便阅读,准备用python-docx中的Inches修改

刚才跑的时候发现写数据库表的时候有一个地方没注意,相同主键不能再次写入,这个需要修改下现在每次解析博文列表时都会先进行删除数据库的操作

没有例外处理,程序容易崩溃 一定要添加例外处理,否则指不定程序在哪里就崩溃了。。

在爬取博文时发现有些博文内容含有表格,以及某些图片是超链接形式,表格在下一版中修改,超链接图片在此版中作为异常处理

体会:

1. 真的真的要做异常处理,否则会很痛苦

2. 分析不全面,没有考虑到含有表格或者其他形式

3. 争取做出GUI,方便处理

4. 添加log 文档, 方便查看出错的地方

python读取数据库数据、并保存为docx_Python - 爬取博客园某一目录下的随笔 - 保存为docx...相关推荐

  1. java 使用webmagic 爬虫框架爬取博客园数据

    java 使用webmagic 爬虫框架爬取博客园数据存入数据库 学习记录   webmagic简介: WebMagic是一个简单灵活的Java爬虫框架.你可以快速开发出一个高效.易维护的爬虫. ht ...

  2. python爬虫:去掉重复的URL(爬取博客园中每页标题和url)

    1.爬取博客园中每页每条新闻的标题和url,在cnblog.py中写入操作内容(增加对每页的爬取) # -*- coding: utf-8 -*- import scrapy import sys i ...

  3. python 爬虫 博客园_Python爬虫爬取博客园作业

    分析一下他们的代码,我在浏览器中对应位置右键,然后点击检查元素,可以找到对应部分的代码.但是,直接查看当前网页的源码发现,里面并没有对应的代码.我猜测这里是根据服务器上的数据动态生成的这部分代码,所以 ...

  4. python 爬虫框架scrapy 入门 爬取博客园新闻(代码)

    1.代码jobbole.py写爬取策略, 2.settings.py  配置pipelines.配置图片下载.配置是否遵循robote协议.数据库配置等 3.pipelines.py 主要是配置数据存 ...

  5. nodejs爬虫与python爬虫_【nodeJS爬虫】前端爬虫系列 -- 小爬「博客园」

    写这篇 blog 其实一开始我是拒绝的,因为爬虫爬的就是cnblog博客园.搞不好编辑看到了就把我的账号给封了:). 言归正传,前端同学可能向来对爬虫不是很感冒,觉得爬虫需要用偏后端的语言,诸如 ph ...

  6. Python读取数据库数据写入Excel

    Python读取数据库数据写入Excel 本文示例: 读取数据库数据 创建Excel文件,并创建指定名称的sheet页 将数据库数据写入创建的sheet页中 保存文件 示例代码: # -*- codi ...

  7. python实现kindle每天推送博客2----python实现爬取博客内容

    python爬虫教程很多, 本文以爬取博客为例 1. Beautiful Soup Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据 为节约篇幅,安装方法自行百度 解析 ...

  8. python 爬取博客访问量并且统计数据成图

    update by 2018-10-01: 开通了一个公众号,多数文章会围绕python写,有兴趣的朋友可以关注哟! 萌生思路 写了csdn博客已有半年之久了,虽然一直当做笔记记录自己的技术成长,但是 ...

  9. python 爬虫动态网页的区别_Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取...

    区别于上篇动态网页抓取,这里介绍另一种方法,即使用浏览器渲染引擎.直接用浏览器在显示网页时解析 HTML.应用 CSS 样式并执行 JavaScript 的语句. 这个方法在爬虫过程中会打开一个浏览器 ...

最新文章

  1. php 代码规范 工具,PHP工具篇:PHPStorm IDE使用CodeSniffer代码规范化管理
  2. 深圳网络推广是如何提高网站的收录比的?
  3. [经典排序算法][集锦]
  4. 堆(Heap)大根堆、小根堆
  5. Boost高性能网络编程
  6. java panel边框_java – 如何在jPanel上设置边框?
  7. 【2019上海网络赛:D】Counting Sequences I(dfs+多重集合排列)
  8. c语言超市,C语言超市收银系统
  9. Reality Shares联合纳斯达克,将推出区块链经济指数
  10. Vue 加载 SVG 图片文件
  11. 最后1天!生信入门转录组和可视化学习捷径
  12. 9_python笔记-函数
  13. ADAMS-Simulink联合仿真-零基础(一)
  14. python创建长度为20的列表_如何在python中创建固定大小列表?
  15. 【Python】python 字符串转数组
  16. Java调用Zebra800条码打印机
  17. 计算机应用专业可以考哪些证,计算机应用技术专业学生需要考取哪些证书?
  18. PAROT: Translating natural language to SPARQL(PAROT:将自然语言翻译成SPARQL)--10
  19. 文件权限修改,启用安全选项卡 - Windows XP
  20. 运放的输出电压摆幅(Output Voltage Swing)

热门文章

  1. TestNG+Maven+IDEA 自动化测试(一) 环境搭建
  2. 算法工程师进化-基础理论
  3. 2017《面向对象程序设计》课程作业七
  4. Android设计模式(十五)--备忘录模式
  5. day1 java基础回顾-多线程
  6. Socket网络编程--Libev库学习(3)
  7. C#仿QQ皮肤-ContextMenuStrip 控件实现
  8. oracle querytimeout,聊聊pg jdbc的queryTimeout及next方法
  9. 国三计算机考试难度大吗,报考计算机技术在职研考试科目多吗考试难度大吗需要有计算机国三基础吗...
  10. python随机生成验证码_Python生成随机验证码