1.爬虫概述
爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,可以自动采集所有其能够访问到的页面内容,以获取相关数据。
2.数据提取
- lxml与XPath
lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。
XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。
XPath使用路径表达式来选区XML文档中的节点或者节点集。
XPath常用规则
提取本地html中的数据
本地html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎来到王者荣耀</h1>
<ul>
<li><a href="https://pvp.qq.com/web201605/herodetail/508.shtml"><img src="https://game.gtimg.cn/images/yxzj/img201606/heroimg/508/508.jpg" alt="">伽罗</a></li>
<li><img src="" alt="">孙策/li>
<li>铠</li>
<li>虞姬</li>
</ul>
<ol>
<li>坦克</li>
<li>战士</li>
<li>刺客</li>
</ol>
<!--div + css 布局-->
<div>这是div标签</div>
<div id="container">
<p>被动:伽罗的普攻与技能伤害将会优先对目标的护盾效果造成一次等额的伤害</p>
<a href="https://www.baidu.com">点击跳转至百度</a>
</div>
<div>这是第二个div标签</div>
</body>
</html>
获取标签<p>数据
from lxml import html
# 读取html文件
with open('./index.html', 'r', encoding='utf-8') as f:
html_data = f.read()
#print(html_data)
# 解析html文件,获得selector对象
selector = html.fromstring(html_data)
# selector中调用xpath方法
# 要获取标签中的内容,末尾要添加text()
h1 = selector.xpath('/html/body/h1/text()')
print(h1[0])
# // 可以代表从任意位置出发、
# //标签1[@属性=属性值]/标签2[@属性=属性值]..../text()
a = selector.xpath('//div[@id="container"]/a/text()')
print(a) # ['点击跳转至百度']
提取远程html中的数据
- Requests库
requests是用来请求网络资源,并可进行简单处理的一个库。
- response常用方法
response = requests.get(url) #发送请求
response .text() #获取str类型的响应
response .content() #获取bytes类型的响应,可用于获取图片
response .headers() #获取响应头(HTTP响应后传输的头部消息)
response .status_code() #获取状态码(网页常见状态码:200-正常,404-找不到网页, 500-服务器异常)
response .request() #获取响应对应的请求
import requests
url = 'https://www.baidu.com'
response = requests.get(url) #发送请求
print(response)
# 获取str类型的响应
#print(response.text)
# 获取bytes类型的响应
print(response.content)
# 获取响应头
print(response.headers)
# 获取状态码
print(response.status_code)
print(response.encoding)
添加响应头headers和查询参数
由于防爬机制,需模拟浏览器,获取和浏览器一致的内容。headers的实行为字典dict。
# 没有添加请求头的知乎网站
resp = requests.get('https://www.zhihu.com/')
print(resp.status_code) #400(请求出错)
# 使用字典定义请求头:数据在网页的检查(F12)的Network中复制
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"}
resp = requests.get('https://www.zhihu.com/', headers = headers)
print(resp.status_code) #200(ok)
3.爬取当当网书籍信息并绘制价格最低的前10家
-
html源码
当当网源码 实现代码
import requests
from lxml import html
import pandas as pd
from matplotlib import pyplot as plt
plt.rcParams["font.sans-serif"] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def spider_dangdang(isbn):
# 目标站点地址
url = 'http://search.dangdang.com/?key={}&act=input'.format(isbn)
# print(url)
header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"}
resp = requests.get(url, headers=header)
html_data = resp.text
# 将html页面写入本地
# with open('dangdang.html', 'w', encoding='utf-8') as f:
# f.write(html_data)
# 提取目标站的信息
selector = html.fromstring(html_data)
ul_list = selector.xpath('//div[@id="search_nature_rg"]/ul/li')
print('您好,一共有{}家店铺售卖次数此书'.format(len(ul_list)))
book_list = []
for li in ul_list:
# 图书名称
title = li.xpath('./a/@title')[0].strip()
print(title)
# 图书购买链接
href = li.xpath('./a/@href')[0]
print(href)
# 图书价格
price = li.xpath('./p[@class="price"]/span[@class="search_now_price"]/text()')[0]
price = float(price.replace("¥"," "))
print(price)
# 图书卖家名称
store = li.xpath('./p[@class="search_shangjia"]/a/text()')
store = '当当自营' if len(store) == 0 else store[0]
print(store)
# 添加每一个商家的图书信息
book_list.append({
'name': title,
'link': href,
'price': price,
'store': store
})
# 按照价格进行排序
book_list.sort(key=lambda x: x['price'])
# 遍历book_list
for book in book_list:
print(book)
# 显示价格最低的前10家 柱状图
top10_store = [book_list[i] for i in range(10)]
# x = []
# for store in top10:
# x.append(store['store'])
x = [x['store'] for x in top10_store]
print(x)
y = [x['price'] for x in top10_store]
print(y)
# plt.bar(x,y)
#barh将横纵坐标反一下
plt.barh(x,y)
plt.show()
# 存储成csv文件
df = pd.DataFrame(book_list)
df.to_csv('dangdang.csv')
spider_dangdang('9787115428028')
爬取结果
-
绘制价格最低的前10家 柱状图
价格最低的前10家店铺
注意
在实现过程中如果出现以下错误:
UnicodeEncodeError: 'gbk' codec can't encode character '\u30fb' in position 36: illegal multibyte sequence。
这是由编码格式不兼容导致的。
解决办法:到File > Settings > Editor > File Ecodings修改编码格式即可