SPIDER-DAY03--Chrome,xpath,lxml
1. Chrome浏览器插件
【1】在线安装
1.1> 下载插件 - google访问助手
1.2> 安装插件 - google访问助手: Chrome浏览器-设置-更多工具-扩展程序-开发者模式-拖拽(解压后的插件)
1.3> 在线安装其他插件 - 打开google访问助手 - google应用商店 - 搜索插件 - 添加即可
【2】爬虫常用插件
2.1》google-access-helper : 谷歌访问助手,可访问 谷歌应用商店
2.2》Xpath Helper: 轻松获取HTML元素的xPath路径
打开/关闭: Ctrl + Shift + x
2.3》JsonView: 格式化输出json格式数据
2.4》Proxy SwitchyOmega: Chrome浏览器中的代理管理扩展程序
==
2.1 xpath定义
XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言,同样适用于HTML文档的检索
2.2 匹配演示
"""
匹配猫眼电影top100:https://maoyan.com/board/4
"""
【1】查找所有的dd节点
//dd
【2】获取所有电影的名称的a节点: 所有class属性值为name的a节点
//p[@class="name"]/a
【3】获取dl节点下第2个dd节点的电影节点
//dl[@class="board-wrapper"]/dd[2]
【4】获取所有电影详情页链接: 获取每个电影的a节点的href的属性值
//p[@class="name"]/a/@href
【注意】
1> 只要涉及到条件,加 [] :
//dl[@class="xxx"] //dl/dd[1] //dl/dd[last()]
2> 只要获取属性值,加 @ :
//dl[@id="xxx"] //p/a/@href
2.3 xpath语法
-
选取节点
【1】// : 从所有节点中查找(包括子节点和后代节点)
【2】@ : 获取属性值
2.1> 使用场景1(属性值作为条件)
//div[@class="movie-item-info"]
2.2> 使用场景2(直接获取属性值)
//div[@class="movie-item-info"]/a/img/@src
【3】练习 - 猫眼电影top100
3.1> 匹配电影名称
//div[@class="movie-item-info"]/p[1]/a/@title
3.2> 匹配电影主演
//div[@class="movie-item-info"]/p[2]/text()
3.3> 匹配上映时间
//div[@class="movie-item-info"]/p[3]/text()
3.4> 匹配电影链接
//div[@class="movie-item-info"]/p[1]/a/@href -
匹配多路径(或)
xpath表达式1 | xpath表达式2 | xpath表达式3 -
常用函数
【1】text() :获取节点的文本内容
xpath表达式末尾不加 /text() :则得到的结果为节点对象
xpath表达式末尾加 /text() 或者 /@href : 则得到结果为字符串
【2】contains() : 匹配属性值中包含某些字符串节点
匹配class属性值中包含 'movie-item' 这个字符串的 div 节点
//div[contains(@class,"movie-item")] -
终极总结
【1】列表中存放字符串: ['', '', '', ...]
xpath表达式的末尾为: /text() 、/@href 得到的列表中为'字符串'
【2】列表中存放节点对象
其他剩余所有情况得到的列表中均为'节点对象'
[<element dd at xxxa>,<element dd at xxxb>,<element dd at xxxc>]
[<element div at xxxa>,<element div at xxxb>]
[<element p at xxxa>,<element p at xxxb>,<element p at xxxc>] -
课堂练习
# www.guazi.com 点击 我要买车
【1】匹配瓜子二手车,所有汽车的链接 :
//ul[@class="carlist clearfix js-top"]/li/a/@href
【2】匹配瓜子二手车-汽车详情页中,汽车的
2.1)名称: //h1[@class="titlebox"]/text()
2.2)里程: //li[@class="two"]/span/text()
2.3)排量: //li[@class="three"]/span/text()
2.4)变速箱: //li[@class="last"]/span/text()
2.5)价格: //span[@class="price-num"]/text()
==3. lxml解析库==
3.1 安装使用流程
【1】安装
sudo pip3 install lxml
【2】使用流程
2.1》导模块 : from lxml import etree
2.2》创建解析对象 : eobj = etree.HTML(html)
2.3》解析对象调用xpath :r_list = eobj.xpath('xpath表达式')
【此生铭记】:只要调用了xpath,得到的结果一定是列表
3.2 lxml+xpath使用
【1】基准xpath: 匹配所有电影信息的节点对象列表
//dl[@class="board-wrapper"]/dd
[<element dd at xxx>,<element dd at xxx>,...]
【2】遍历对象列表,依次获取每个电影信息
item = {}
for dd in dd_list:
item['name'] = dd.xpath('.//p[@class="name"]/a/text()').strip()
item['star'] = dd.xpath('.//p[@class="star"]/text()').strip()
item['time'] = dd.xpath('.//p[@class="releasetime"]/text()').strip()
4. 豆瓣图书爬虫
4.1 需求分析
【1】抓取目标 - 豆瓣图书top250的图书信息
https://book.douban.com/top250?start=0
https://book.douban.com/top250?start=25
https://book.douban.com/top250?start=50
... ...
【2】抓取数据
2.1) 书籍名称 :红楼梦
2.2) 书籍描述 :[清] 曹雪芹 著 / 人民文学出版社 / 1996-12 / 59.70元
2.3) 书籍评分 :9.6
2.4) 评价人数 :286382人评价
2.5) 书籍类型 :都云作者痴,谁解其中味?
4.2 实现流程
【1】确认数据来源 - 响应内容存在
【2】分析URL地址规律 - start为0 25 50 75 ...
【3】xpath表达式
3.1) 基准xpath,匹配每本书籍的节点对象列表
//div[@class="indent"]/table
3.2) 依次遍历每本书籍的节点对象,提取具体书籍数据
书籍名称 : .//div[@class="pl2"]/a/@title
书籍描述 : .//p[@class="pl"]/text()
书籍评分 : .//span[@class="rating_nums"]/text()
评价人数 : .//span[@class="pl"]/text()
书籍类型 : .//span[@class="inq"]/text()
4.3 代码实现
"""
lxml + xpath 抓取豆瓣图书top250
"""
import requests
from lxml import etree
import time
import random
from fake_useragent import UserAgent
class BookSpider:
def __init__(self):
self.url = 'https://book.douban.com/top250?start={}'
def get_html(self, url):
"""请求+解析+数据处理"""
headers = {'User-Agent': UserAgent().random}
html = requests.get(url=url, headers=headers).text
# 直接调用解析函数
self.parse_html(html)
def parse_html(self, html):
"""lxml + xpath解析提取数据"""
# 1.创建解析对象
eobj = etree.HTML(html)
table_list = eobj.xpath('//table')
for table in table_list:
"""书的信息要一个一个提取"""
item = {}
# 名称
title_list = table.xpath('.//div[@class="pl2"]/a/@title')
item['title'] = title_list[0] if title_list else None
# 信息
info_list = table.xpath('.//p[@class="pl"]/text()')
item['info'] = info_list[0] if info_list else None
# 评分
score_list = table.xpath('.//span[@class="rating_nums"]/text()')
item['score'] = score_list[0] if score_list else None
# 评价人数
commit_list = table.xpath('.//span[@class="pl"]/text()')
item['commit'] = commit_list[0][1:-1].strip() if commit_list else None
# 描述
comment_list = table.xpath('.//span[@class="inq"]/text()')
item['comment'] = comment_list[0] if comment_list else None
print(item)
def crawl(self):
for page in range(1, 11):
start = (page - 1) * 25
page_url = self.url.format(start)
self.get_html(url=page_url)
# 控制数据抓取频率
time.sleep(random.uniform(0, 2))
if __name__ == '__main__':
spider = BookSpider()
spider.crawl()
5. 百度贴吧小视频爬虫
5.1 需求分析
【1】官网地址:进入某个百度贴吧,寻找有视频的帖子,比如如下帖子链接:
https://tieba.baidu.com/p/7185877941
【2】目标
2.1> 在此帖子中提取中具体视频的链接(src)
2.2> 将视频抓取保存到本地文件(向src发请求获取bytes数据类型,以wb方式保存到本地)
5.2 实现流程
【1】确认数据来源 : 静态!!! 【2】帖子中视频的xpath表达式 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主 ### 重要:页面中xpath不能全信,一切以响应内容为主
5.3 代码实现
"""
百度贴吧视频抓取
1、向帖子链接发请求,提取具体:视频的链接
2、向视频的链接发请求,将响应内容以 wb 的方式保存到本地文件
"""
import requests
from lxml import etree
from fake_useragent import UserAgent
# 1.提取帖子中视频的链接
url = 'https://tieba.baidu.com/p/7216913650'
headers = {'User-Agent' : UserAgent().random}
html = requests.get(url=url, headers=headers).text
eobj = etree.HTML(html)
src_list = eobj.xpath('//embed/@data-video')
if src_list:
video_url = src_list[0]
# 向视频链接发请求,并将其保存到本地即可
video_html = requests.get(url=video_url, headers=headers).content
with open('赵丽颖.mp4', 'wb') as f:
f.write(video_html)
else:
print('提取视频链接失败')
6. 今日作业
【1】链家二手房爬虫
# 注意: 一切以响应内容为准
1.1> 官网地址:进入链家官网,点击二手房 : https://bj.lianjia.com/ershoufang/
1.2> 目标 : 抓取100页的二手房源信息,包含房源的:
名称
地址
户型、面积、方位、是否精装、楼层、年代、类型
总价
单价
1.3> 数据处理
将数据分别存入:MySQL、MongoDB、csv文件中

浙公网安备 33010602011771号