Python网络数据抓取实战——Xpath解析豆瓣书评
时间:2022-05-08
本文章向大家介绍Python网络数据抓取实战——Xpath解析豆瓣书评,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前两篇我详细的讲解了CSS和XPath表达式在网页解析中的用法,但是都是以列举和解释为主,并没有用于解决实战问题,今天这一篇,我使用urllib+lxml工具组合,结合XPath表达式来做一个小案例。
该案例是刘顺祥大神【公众号:每天进步一点点】中使用的爬虫实战案例,他用的request+BeautifulSoup,这样刚好扩展下XPath的用法,丰富一下该案例:
https://read.douban.com/search?q=Python
#! /usr/bin/env python
#coding=utf-8
from urllib.request import urlopen,Request
import pandas as pd
import numpy as np
from lxml import etree
url='https://read.douban.com/search?q=Python'
header ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36'}
构建解析函数:
def getcontent(url):
i=0
myresult={}
title=[];subtitle=[];author=[];category=[];price=[];rating=[];eveluate_nums=[]
for page in range(0,4):
link=url+'&start='+str(page*10)
content=urlopen(Request(link,headers=header)).read().decode('utf-8')
result=etree.HTML(content)
###计算每一页有多少条书籍信息:
length=len(result.xpath("//ol[@class='ebook-list column-list']/li"))
###提取图书标题信息:
title.extend(result.xpath("//ol/li//div[@class='title']/a/text()| //ol/li//h4/a/text()"))
###考虑作者不唯一的情况:
author_text=[np.nan]*length
for i in range(1,length+1):
author_text[i-1]=result.xpath("//li[{0}]//span[contains(text(),'作者')]/following-sibling::*[1]/a/text() | //li[{0}]//div[@class='author']/a/text()".format(i))
author.extend(author_text)
###考虑分类,枚举出所有分类标签
category.extend(result.xpath("//span[@class='category']/span[2]/span/text() | //p[@class='category']/span[@class='labled-text']/text() | //div[@class='category']/text()"))
###考虑副标题是否存在
subtext=[np.nan]*length
for i in range(1,length+1):
if result.xpath("//ol/li[{}]//p/text()".format(i)) != []:
subtext[i-1]=result.xpath("//ol/li[{}]//p/text()".format(i))
subtitle.extend(subtext)
###考虑评价是否存在:
eveluate_text=[np.nan]*length
for i in range(1,length+1):
if result.xpath("//ol/li[{}]//a[@class='ratings-link']/span/text()".format(i)) != []:
eveluate_text[i-1]=result.xpath("//ol/li[{}]//a[@class='ratings-link']/span/text()".format(i))
eveluate_nums.extend(eveluate_text)
###考虑评分是否存在:
rating_text=[np.nan]*length
for i in range(1,length+1):
if result.xpath("//ol/li[{}]//div[@class='rating list-rating']/span[2]/text()".format(i)) != []:
rating_text[i-1]=result.xpath("//ol/li[{}]//div[@class='rating list-rating']/span[2]/text()".format(i))
rating.extend(eveluate_text)
###考虑价格是否存在:
price_text=[np.nan]*length
for i in range(1,length+1):
if result.xpath("//ol/li[{}]/div[@class='info']//span[@class='price-tag discount']/span/text()".format(i)) != []:
price_text[i-1]=result.xpath("//ol/li[{}]/div[@class='info']//span[@class='price-tag discount']/span/text()".format(i))
price.extend(eveluate_text)
print("page {} is over!!!".format(page))
print("everything is OK")
myresult={"title":title,"subtitle":subtitle,"author":author,"category":category,"price":price,"rating":rating,"eveluate_nums":eveluate_nums}
return myresult
运行函数:
url="https://read.douban.com/search?q=Python"
myresult=getcontent(url)
查看变量信息
for i,m in myresult.items():
print(i+":"+str(len(m)))
title:39
subtitle:39
author:39
category:39
price:39
rating:39
eveluate_nums:39
铺平嵌套列表:
以上可以看到有几列是嵌套列表,会影响我们后期的数据分析,所以需要铺平列表,这里是一个我从网上找到的列表解除嵌套的代码。
def flatten(input_list):
output_list = []
while True:
if input_list == []:
break
for index, i in enumerate(input_list):
if type(i)== list:
input_list = i + input_list[index+1:]
break
else:
output_list.append(i)
input_list.pop(index)
break
return output_list
myresult['eveluate_nums']=flatten(myresult['eveluate_nums'])
myresult['price']=flatten(myresult['price'])
myresult['rating']=flatten(myresult['rating'])
myresult['subtitle']=flatten(myresult['subtitle'])
批量修改变量格式:
mydata=pd.DataFrame(myresult)
mydata=mydata.astype({'author':'str','category':'str','eveluate_nums':'float', 'price':'float', 'rating':'float', 'subtitle':'str','title':'str'})
mydata.columns
mydata.dtypes
author object
category object
eveluate_nums float64
price float64
rating float64
subtitle object
title object
dtype: object
参考资料: http://blog.csdn.net/vola9527/article/details/68964144 https://mp.weixin.qq.com/s?__biz=MzIxNjA2ODUzNg==&mid=2651435242&idx=1&sn=f9315b81911bbc4f83f41ddba23d054e
往期案例数据请移步本人GitHub: https://github.com/ljtyduyu/DataWarehouse/tree/master/File
- python爬虫(六)_urllib2:handle处理器和自定义opener
- Hbase多版本的读写(Shell&Java API版)
- 总结---3
- Mac系统实现git命令自动补全
- [大数据之Yarn]——资源调度浅学
- Mac系统的终端显示git当前分支
- 不掌握这几个人工智能编程语言怎么能说懂AI
- Gulp实现css、js、图片的压缩以及css、js文件的MD5命名
- 大数据之Yarn——Capacity调度器概念以及配置
- 移动端web开发,click touch tap区别
- 大数据学习之路(持续更新中...)
- 如何养成良好的c++编程习惯(1)——内存管理
- 使用jOrgChart插件实现组织架构图的展示
- Spark源码分析 之 Driver和Excutor是怎么跑起来的?(2.2.0版本)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法