HTML数据解析

诸如爬虫类场景下我们需要对抓取的HTML做内容解析,提取感兴趣的内容,python标准库提供了HTMLParser\SGMLParser两个模块用于解析HTML,然而这两个模块的实现方式都很难理解,用来做遍历查找实在是很不友好,第三方库lxml则简单许多,逻辑上更容易理解,而且同时支持HTML和XML两类结构化数据解析

用官方话说:

“lxml provides a very simple and powerful API for parsing XML and HTML. It supports one-step parsing as well as step-by-step parsing using an event-driven API (currently only for XML).”

Parsing HTML with lxml

从html中提取感兴趣的内容, 一种选择是用正则表达式, 不过正则表达式写起来太痛苦,万不得已不用也罢。html语言可以看做是类似xml的层次化结构语言, 可以解析成一个树,然后用xpath语言做数据定位提取.

实现一个小爬虫的思路

Python Documentation 中 HTMLParser章节Example中用一个网站做演示如何使用HTMLParser解析HTML,这里我也借用这个网站做演示,该网站总工有10页,页面下方有“Next”链接到下一页,内容是罗列一堆名人名言,关键信息为“名言”、“作者”、“关键字”,我就遍历这10个页面并提取这三个信息。

http://quotes.toscrape.com

  • requests.get(url)抓取一个链接的页面;
  • 抓取的页面字符形式喂给 lxml.html.fromstring();
  • XPath定位并提取感兴趣的内容;
  • 数据写入MySQL;

代码 & Walk Through


#-*- coding:utf-8 -*-
'''
Created on 2017年7月3日@author: will
'''
import MySQLdb
from lxml import html
import requestsclass Pipeline():'''数据库连接,已在MySQL Server上提前创建db = Locust'''connDB = MySQLdb.connect(host = '192.168.8.82',port = 3306,user = 'willyan',passwd = 'will392891',db = 'Locust',charset = 'utf8')cur = connDB.cursor()class HtmlPar():'''解析并提取html文件中的感兴趣信息,'''    def myPar(self,start_url):##创建urls列表,用于存放待爬取的页面链接##爬虫起始页链接start_url需要作为参数传入并存放到urls[],提取页面底部“Next"的 href 添加到urls[]urls = []urls.append(start_url)##创建三个list分别用于存放提取到的名言、作者、关键字text = []author = []tags = []'''定义一个条件循环体,从urls[]中提取待爬取页面的链接,爬取结果以字符形式喂给解析器,提取“Next”元素,若“Next”元素存在,则将其“href”信息添加到urls[]列表中,作为下一次循环爬取的目标链接,同时提取页面中的全部“名言Text”、“作者author”、“关键字 tags”分别添加到对应的list,当爬取的页面中定位不到“Next"元素时说明已到达最后一页跳出循环并将提取到的三个List返回。'''       i = 0while True:#从urls[]依次取待爬取页面链接,爬取结果以字符形式喂给解析器page = requests.get(urls[i])tree = html.fromstring(page.text)#提取页面底部的“Next”元素,作为判读是否继续爬取的依据nextPage = tree.xpath('//nav/ul/li[@class="next"]/a/@href')##当nextPage 返回为空[]时,说明已到末页,应终止循环并将提取到的全部数据返回if nextPage != []:#提取当前页面“Next”元素的“href”链接数据,并添加到urls[]作为下一次循环的爬取目标urls.append(urls[0] + tree.xpath('//nav/ul/li[@class="next"]/a/@href')[0])#提取的名言、作者、关键字三个信息都是以list[]形式返回,以len()函数识别其中一个对象的长度(如名言或作者),定义for循环将返回的三个list[]内容依次添加到text[]、author[]、tags[]中。num = len(tree.xpath('//span[@itemprop="text"]/text()'))for x in range(num):text.append(tree.xpath('//span[@itemprop="text"]/text()')[x])author.append(tree.xpath('//small[@itemprop="author"]/text()')[x])tags.append(tree.xpath('//meta/@content')[x])else:return text, author, tagsi += 1if __name__ == '__main__':#数据库中建表qutes,用于存放抓取的数据db = Pipeline()conn = db.connDBcur = db.curdbCreateCMD = 'create table quotes(quoteID varchar(10), quoteText varchar(600), author varchar(20), tags varchar(20), primary key (quoteID), unique(quoteID)) ENGINE=InnoDB DEFAULT CHARSET=utf8'cur.execute(dbCreateCMD)#定义起始爬取页start_url = 'http://quotes.toscrape.com'quotes = HtmlPar()result =  quotes.myPar(start_url)#将返回的三维元组数据循环写入数据库,返回数据格式为: result(text[...],author[...],tags[...])for y in range(len(result[0])):#Text部分有的条目字符数太多,超过MySQL字符限制无法写入,所以text部分就不写库了。。。cmd = "insert ignore into quotes(quoteID, author, tags) values('" + str(y+1) + "', '" + result[1][y] + "', '" + result[2][y] + "')"cur.execute(cmd)conn.commit()cur.close()conn.close()

执行结果

进数据库Locust查看,总计抓取了90条内容。

mysql> select * from quotes;
Empty set (0.01 sec)mysql> select * from quotes;
+---------+-----------+----------------------+----------------------+
| quoteID | quoteText | author               | tags                 |
+---------+-----------+----------------------+----------------------+
| 1       | NULL      | Albert Einstein      | change,deep-thoughts |
| 10      | NULL      | Steve Martin         | humor,obvious,simile |
| 11      | NULL      | Marilyn Monroe       | friends,heartbreak,i |
| 12      | NULL      | J.K. Rowling         | courage,friends      |
| 13      | NULL      | Albert Einstein      | simplicity,understan |
| 14      | NULL      | Bob Marley           | love                 |
| 15      | NULL      | Dr. Seuss            | fantasy              |
| 16      | NULL      | Douglas Adams        | life,navigation      |
| 17      | NULL      | Elie Wiesel          | activism,apathy,hate |
| 18      | NULL      | Friedrich Nietzsche  | friendship,lack-of-f |
| 19      | NULL      | Mark Twain           | books,contentment,fr |
| 2       | NULL      | J.K. Rowling         | abilities,choices    |
| 20      | NULL      | Allen Saunders       | fate,life,misattribu |
| 21      | NULL      | Pablo Neruda         | love,poetry          |
| 22      | NULL      | Ralph Waldo Emerson  | happiness            |
| 23      | NULL      | Mother Teresa        | attributed-no-source |
| 24      | NULL      | Garrison Keillor     | humor,religion       |
| 25      | NULL      | Jim Henson           | humor                |
| 26      | NULL      | Dr. Seuss            | comedy,life,yourself |
| 27      | NULL      | Albert Einstein      | children,fairy-tales |
| 28      | NULL      | J.K. Rowling         |                      |
| 29      | NULL      | Albert Einstein      | imagination          |
| 3       | NULL      | Albert Einstein      | inspirational,life,l |
| 30      | NULL      | Bob Marley           | music                |
| 31      | NULL      | Dr. Seuss            | learning,reading,seu |
| 32      | NULL      | J.K. Rowling         | dumbledore           |
| 33      | NULL      | Bob Marley           | friendship           |
| 34      | NULL      | Mother Teresa        | misattributed-to-mot |
| 35      | NULL      | J.K. Rowling         | death,inspirational  |
| 36      | NULL      | Charles M. Schulz    | chocolate,food,humor |
| 37      | NULL      | William Nicholson    | misattributed-to-c-s |
| 38      | NULL      | Albert Einstein      | knowledge,learning,u |
| 39      | NULL      | Jorge Luis Borges    | books,library        |
| 4       | NULL      | Jane Austen          | aliteracy,books,clas |
| 40      | NULL      | George Eliot         | inspirational        |
| 41      | NULL      | George R.R. Martin   | read,readers,reading |
| 42      | NULL      | C.S. Lewis           | books,inspirational, |
| 43      | NULL      | Marilyn Monroe       |                      |
| 44      | NULL      | Marilyn Monroe       | girls,love           |
| 45      | NULL      | Albert Einstein      | life,simile          |
| 46      | NULL      | Marilyn Monroe       | love                 |
| 47      | NULL      | Marilyn Monroe       | attributed-no-source |
| 48      | NULL      | Martin Luther King J | hope,inspirational   |
| 49      | NULL      | J.K. Rowling         | dumbledore           |
| 5       | NULL      | Marilyn Monroe       | be-yourself,inspirat |
| 50      | NULL      | James Baldwin        | love                 |
| 51      | NULL      | Jane Austen          | friendship,love      |
| 52      | NULL      | Eleanor Roosevelt    | attributed,fear,insp |
| 53      | NULL      | Marilyn Monroe       | attributed-no-source |
| 54      | NULL      | Albert Einstein      | music                |
| 55      | NULL      | Haruki Murakami      | books,thought        |
| 56      | NULL      | Alexandre Dumas fils | misattributed-to-ein |
| 57      | NULL      | Stephenie Meyer      | drug,romance,simile  |
| 58      | NULL      | Ernest Hemingway     | books,friends,noveli |
| 59      | NULL      | Helen Keller         | inspirational        |
| 6       | NULL      | Albert Einstein      | adulthood,success,va |
| 60      | NULL      | George Bernard Shaw  | inspirational,life,y |
| 61      | NULL      | Charles Bukowski     | alcohol              |
| 62      | NULL      | Suzanne Collins      | the-hunger-games     |
| 63      | NULL      | Suzanne Collins      | humor                |
| 64      | NULL      | C.S. Lewis           | love                 |
| 65      | NULL      | J.R.R. Tolkien       | bilbo,journey,lost,q |
| 66      | NULL      | J.K. Rowling         | live-death-love      |
| 67      | NULL      | Ernest Hemingway     | good,writing         |
| 68      | NULL      | Ralph Waldo Emerson  | life,regrets         |
| 69      | NULL      | Mark Twain           | education            |
| 7       | NULL      | André Gide           | life,love            |
| 70      | NULL      | Dr. Seuss            | troubles             |
| 71      | NULL      | Alfred Tennyson      | friendship,love      |
| 72      | NULL      | Charles Bukowski     | humor                |
| 73      | NULL      | Terry Pratchett      | humor,open-mind,thin |
| 74      | NULL      | Dr. Seuss            | humor,philosophy     |
| 75      | NULL      | J.D. Salinger        | authors,books,litera |
| 76      | NULL      | George Carlin        | humor,insanity,lies, |
| 77      | NULL      | John Lennon          | beatles,connection,d |
| 78      | NULL      | W.C. Fields          | humor,sinister       |
| 79      | NULL      | Ayn Rand             |                      |
| 8       | NULL      | Thomas A. Edison     | edison,failure,inspi |
| 80      | NULL      | Mark Twain           | books,classic,readin |
| 81      | NULL      | Albert Einstein      | mistakes             |
| 82      | NULL      | Jane Austen          | humor,love,romantic, |
| 83      | NULL      | J.K. Rowling         | integrity            |
| 84      | NULL      | Jane Austen          | books,library,readin |
| 85      | NULL      | Jane Austen          | elizabeth-bennet,jan |
| 86      | NULL      | C.S. Lewis           | age,fairytales,growi |
| 87      | NULL      | C.S. Lewis           | god                  |
| 88      | NULL      | Mark Twain           | death,life           |
| 89      | NULL      | Mark Twain           | misattributed-mark-t |
| 9       | NULL      | Eleanor Roosevelt    | misattributed-eleano |
| 90      | NULL      | C.S. Lewis           | christianity,faith,r |
+---------+-----------+----------------------+----------------------+
90 rows in set (0.01 sec)

多线程优化

对于页面数较多的站点爬取可以考虑使用multiprocessing库做多线程处理,先爬取所有页面的链接,再以多线程做爬取页面和数据提取以提高爬虫效率。

使用lxml解析HTML数据相关推荐

  1. 【Python爬虫学习实践】基于BeautifulSoup的网站解析及数据可视化

    在上一次的学习实践中,我们以Tencent职位信息网站为例,介绍了在爬虫中如何分析待解析的网站结构,同时也说明了利用Xpath和lxml解析网站的一般化流程.在本节的实践中,我们将以中国天气网为例,并 ...

  2. python解析xml数据_数据开发_Python解析XML文件

    解析XML文件 XML是可扩展标记语言,主要用于传输和存储数据 解析方式 使用lxml解析 主要注意: text tag attrib 使用方式 有 get() 以及迭代的情况 数据示例 a31 代码 ...

  3. Python爬虫入门之爬虫解析提取数据的四种方法

    本文主要介绍了Python爬虫入门之爬虫解析提取数据的四种方法,通过具体的内容向大家展现,希望对大家Python爬虫的学习有所帮助. 基础爬虫的固定模式 笔者这里所谈的基础爬虫,指的是不需要处理像异步 ...

  4. 爬虫爬取京东商品详细数据 (品牌、售价、各类评论量(精确数量)、热评词及数量等)json解析部分数据

    文章目录 前言 一.数据保存格式设置及数据库准备(CentOS云mysql数据库) 1.分析数据需求(单一商品为例) 2.数据库保存格式 3.用到的数据库操作及指令 二.网页分析 1.分析网页源码,确 ...

  5. 爬虫解析提取数据的四种方法

    一.分析网页 以经典的爬取豆瓣电影 Top250 信息为例.每条电影信息在 ol class 为 grid_view 下的 li 标签里,获取到所有 li 标签的内容,然后遍历,就可以从中提取出每一条 ...

  6. Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息

    本次爬虫的目标是汽车之家的二手车销售信息,范围是全国,不过很可惜,汽车之家只显示100页信息,每页48条,也就是说最多只能够爬取4800条信息. 由于这次爬虫的主要目的是使用lxml解析器,所以在信息 ...

  7. 深入分析jquery解析json数据

    我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. JSON数据如下,是一个嵌套JSON: {"comments":[{& ...

  8. pandas使用read_csv函数读取文件并解析日期数据列(parse dates)、pandas使用read_csv函数读取文件并将缺失值转化为空字符串

    pandas使用read_csv函数读取文件并解析日期数据列(parse dates).pandas使用read_csv函数读取文件并将缺失值转化为空字符串 目录

  9. java构造和解析json_Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

最新文章

  1. DeprecationWarning: the md5 module is deprecated; use hashlib instead import md5
  2. latex 1图加标题_学习|Latex排版
  3. tensorflow 保存训练loss_tensorflow2.0保存和加载模型 (tensorflow2.0官方教程翻译)
  4. Html5 h5页面输入框失去焦点页面底部白板问题
  5. MATLAB中if (0)
  6. 字符串是通过“引用”传递的
  7. 电商管理系统的作用?好用的电商管理系统有哪些特点?
  8. 计算机死机代码怎么写,如何用代码让电脑死机
  9. 我感觉被骗了,微信内测 “大小号” 功能,同一手机号可注册两个微信
  10. 微信网页授权登录demo
  11. 一个游戏程序员的学习资料(全是好书)
  12. 电车要迎来大爆发?华州电车的额外补贴要来了
  13. python画蝴蝶结_Shapely用户手册
  14. 站在智慧医院的制高点 阜外华中心血管病医院探索数字化融合实践
  15. 百数谐韵咏物千字文全文释义
  16. ev3和python哪个好_乐高教育EV3比SPIKE Prime更好的十个理由!
  17. 为什么华为、阿里、字节跳动、微软等都走上了云原生和数字化之路?
  18. 用VB.NET实现你的游戏梦想Java教程
  19. Linux CentOS7 基础:网络管理技术
  20. 从GCT的成绩看问题

热门文章

  1. “华为杯”第十八届中国研究生数学建模竞赛D题:抗乳腺癌候选药物的优化建模(一等奖)
  2. linux命令touch意思,linux的touch命令的详细解释
  3. 海格里斯HEGERLS建议:引进和建设自动分拣系统时要考虑这些条件
  4. 如何设计数据库(2)?
  5. 老电脑如何利用云服务器提升性能,把旧电脑变成云电脑?让手机运行大型PC游戏...
  6. 5G LTE窄带物联网(NB-IoT) 3
  7. 数据分析工具--matplotlib
  8. 基于Android和PHP学生考勤管理系统设计与实现
  9. TDS协议 加密密码算法
  10. CentOS ping xxx.xxx.xxx.xxx ,未知的名称或服务解决办法