今天学习的依旧是爬虫应用开发,Xpath涵盖的Requests库高级用法和Xpath的基本用法,包括老师给我们还进行了一个人邮图书爬取案例,request 库高级用法包括绘画设置文件上传SSL证书验证和代理设置,如果使用session实现维护一个绘画,具体代码是如下:
import requests
login_url="https://wx.mail.qq.com/"
data={
"username":"usernmae",
"password":"********",
}
#使用实例化requests.session
session=requests.session()
#使用对象session 记录登录后的cookie值
session.post(url=login_url,data=data)
#使用对象session 记录的cookie值进行不用密码登录
#下面的url网址是依据自己的账号、密码登录进去的url
url = "https://mail.qq.com/*************"
response=session.get(url=login_url)
print(response.text)
Xpath的基本用法:
对于网页的节点来说,可以定义id、class或其他属性,而且节点之间还有层次关系,在网页中可以通过XPath或css选择器来定位一个或多个节点。在页面解析时,利用XPath或css选择器来提取某个节点,然后再调用相应方法获取正文内容或者属性,就可以提取我们想要的任意信息了。
Python提供了多种解析库,常用的解析库如下:llxml、lBeautifulSoup、lpyquery、parsel。
Xpath它是一种用来确定XML文档中某部分位置的语言被开发者用来当作小型查询语言。lxml库是一种执行效率高,并且简单易学的第三方网页解析库他不是一种Python标准库也是需要自己安装的,可以在命令下使用pip命令安装。
关于Xpath的基本用法有几个代码为例。
import requests
import csv
from lxml import etree
def get_html(url): # 获取网页内容
try:
r = requests.get(url) # 发送请求
r.encoding = r.apparent_encoding # 设置返回内容的字符集编码
r.raise_for_status() # 非正常返回抛出异常
return r.text # 返回网页的文本内容
except Exception as error:
print(error)
result_list = [] # 存放爬取内容
def parse(html): # 解析
html = etree.HTML(html)
for row in html.xpath('//*[@id="tag-book"]/div/ul/li/div[2]'):
name = row.xpath('h4/a/text()')[0] # 书名
print('name', name)
url = row.xpath('h4/a/@href')[0] # 链接详情
# print('url', url)
author = row.xpath('div/span/text()')[0].strip() # 作者
# print('author', author)
price = row.xpath('span/span/text()')[0] # 价格
# print('price', price)
item = [name, url, author, price] # 标题,链接详情
result_list.append(item)
return result_list
def save(item, path):
with open(path, "w+", newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerows(item)
if __name__ == "__main__":
url = "https://www.ryjiaoyu.com/tag/details/7"
html = get_html(url)
parse(html) # 引用parse函数,爬取内容
save(result_list, "./图书.csv") # 列表形式保存
import requests
def get_html(url, time=30):
try:
r = requests.get(url, timeout=time) # 带超时设置的GET请求
r.encoding = r.apparent_encoding # 设置编码
r.raise_for_status() # 非200状态码抛出异常
return r.text # 返回网页文本
except Exception as error:
print(error)
from lxml import etree
def parser(html):
doc = etree.HTML(html) # 解析HTML
title = doc.xpath("//div[@id='rankWrap']//li/@title") # 歌曲名
href = doc.xpath("//div[@id='rankWrap']//li/a/@href") # 播放链接
out_dict = {"歌曲": title, "地址": href} # 用字典存储
return out_dict
import pandas
def save_dict2csv(item, path):
df = pandas.DataFrame(item) # 转换为DataFrame
df.to_csv(path) # 保存为CSVv
if __name__ == "__main__":
url = "http://www.bspider.top/kugou/"
html = get_html(url) # 获取网页数据
out_dict = parser(html) # 解析数据
save_dict2csv(out_dict, "music.csv") # 保存数据
import requests
def get_html(url, time=30):
try:
r = requests.get(url, timeout=time) # 带超时设置的GET请求
r.encoding = r.apparent_encoding # 设置编码
r.raise_for_status() # 非200状态码抛出异常
return r.text # 返回网页文本
except Exception as error:
print(error)
from lxml import etree
def parser(html):
doc = etree.HTML(html) # 解析HTML
out_list = [] # 存储解析结果
# 遍历每个小说节点
for row in doc.xpath("//*[@class='book-img-text']//li/*[@class='book-mid-info']"):
row_data = [
row.xpath("h4/a/text()")[0], # 小说名称
row.xpath("p[@class='author']/a/text()")[0], # 作者
row.xpath("p[2]/text()")[0].strip(), # 摘要(去除空格)
row.xpath("p[@class='update']/span/text()")[0] # 更新日期
]
out_list.append(row_data)
return out_list
import csv
def save_csv(item, path):
# 打开文件(utf-8编码,避免中文乱码)
with open(path, "at", newline='', encoding="utf-8") as f:
csv_write = csv.writer(f) # 创建写入对象
csv_write.writerows(item) # 批量写入
if __name__ == "__main__":
# 爬取1-5页(可根据需求调整页码范围)
for i in range(1, 6):
url = "http://www.bspider.top/qidian/?page={0}".format(i) # 拼接分页URL
html = get_html(url) # 获取网页数据
out_list = parser(html) # 解析数据
save_csv(out_list, "小说.csv") # 保存数据
然后第三个作业是应用以上案例,自己爬取一个网站,我选择爬取的是豆瓣读书的科技类图书列表。
我此段代码主要分为三个步骤:发送 HTTP 请求获取网页内容,使用 XPath 解析 HTML 提取图书信息,再将提取的数据保存为 CSV 文件。不过还是可以进行二次优化的。
- 类封装:将爬虫功能封装在
DoubanBookSpider类中,使代码结构更清晰 - 多页爬取:增加了
crawl方法支持多页爬取,通过修改pages参数可以获取更多数据 - 数据解析增强:完善了出版信息的解析,现在可以提取出版社、出版日期和价格
- 异常处理细化:针对 HTTP 请求异常和解析异常分别处理
- 评价人数提取:增加了对评价人数的提取。进行完这些优化我的代码也许可以更加完整!

被折叠的 条评论
为什么被折叠?



