shy:数据爬取与可视化技术系列已发文三篇了,更多爬虫技术请查看专栏文章。
数据爬取与可视化技术——使用XPath和lxml库爬取、解析、提取数据
shy:现已开辟专栏四个:C++、ACM、数据库系统概论、数据爬取与可视化技术,更多文章请关注主页@HUAYI_SUN Blog
文章目录
问题描述:
爬取新浪股票吧的数据,其URL格式为https://guba.sina.com.cn/?s=bar&name=sh000300&type=0&page=1。分析其URL格式,并注意查看response的编码。添加数据提取功能,要求报告股吧的标题、作者和发表时间,将以上三个属性封装成item对象,并将每页的item封装到items数组中。要求股票代码由用户输入,同时输入起始页和结束页,把爬取到的网页保存成html文件。
Code:
import urllib.parse
import urllib.request
# from requests import get, post
from lxml import etree
import time
# enconding = 'utf-8'
def load_page(url, filename):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
"Cookie": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
} # 此处加入自己的Cookie
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
return response.read().decode('gbk')
def parse_page(html):
# 标题: //*[@id="blk_list_02"]/table/tbody/tr[2]/td[3]/a/text()
# 作者://*[@id="blk_list_02"]/table/tbody/tr[2]/td[4]/div/a/text()
# 发表时间://*[@id="blk_list_02"]/table/tbody/tr[2]/td[5]/text()
root = etree.HTML(html)
lis = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr')
# print(len(lis))
items = []
for i in range(2, len(lis) + 1):
name = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[3]/a/text()')
price = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[4]/div/a/text()')
attr = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[5]/text()')
item = {"标题": name, "作者": price, "发表时间": attr}
items.append(item)
print(items)
def write_page(html, filename):
print("正在保存", filename)
with open(filename, 'w', encoding='gbk') as file:
file.write(html)
def sina_stock_spider(stock_code, begin, end):
base_url = "https://guba.sina.com.cn/?s=bar&name={}&type=0&page="
for page in range(int(begin), int(end) + 1):
url = base_url.format(stock_code) + str(page)
print("正在爬取:", url)
html = load_page(url, "")
# print(html)
parse_page(html)
filename = f"D:\\sina_stock_{stock_code}_page_{page}.html"
write_page(html, filename)
time.sleep(1)
if __name__ == "__main__":
stock_code = input("请输入股票代码(如sh000300): ")
begin = input("请输入起始页码:")
end = input("请输入结束页码:")
sina_stock_spider(stock_code, begin, end)
分析:
导入模块
import urllib.parse
import urllib.request
from lxml import etree
import time
urllib.parse
:用于解析 URL。urllib.request
:用于发送 HTTP 请求。lxml.etree
:用于解析 HTML。time
:用于处理时间。
load_page 函数
def load_page(url, filename):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
"Cookie": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
} # 此处加入自己的Cookie
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request)
return response.read().decode('gbk')
- 功能:加载指定 URL 的页面内容。
- 参数:
url
表示要加载的页面 URL,filename
表示要保存的文件名。 - 返回值:返回解码后的 HTML 内容。
parse_page 函数
def parse_page(html):
root = etree.HTML(html)
lis = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr')
items = []
for i in range(2, len(lis) + 1):
name = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[3]/a/text()')
price = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[4]/div/a/text()')
attr = root.xpath('//*[@id="blk_list_02"]/table/tbody/tr[' + str(i) + ']/td[5]/text()')
item = {"标题": name, "作者": price, "发表时间": attr}
items.append(item)
print(items)
- 功能:解析页面内容,提取帖子的标题、作者和发表时间。
- 参数:
html
表示要解析的 HTML 内容。 - 输出:打印解析后的帖子信息。
write_page 函数
def write_page(html, filename):
print("正在保存", filename)
with open(filename, 'w', encoding='gbk') as file:
file.write(html)
- 功能:将页面内容写入文件。
- 参数:
html
表示要写入文件的 HTML 内容,filename
表示要保存的文件名。
sina_stock_spider 函数
def sina_stock_spider(stock_code, begin, end):
base_url = "https://guba.sina.com.cn/?s=bar&name={}&type=0&page="
for page in range(int(begin), int(end) + 1):
url = base_url.format(stock_code) + str(page)
print("正在爬取:", url)
html = load_page(url, "")
parse_page(html)
filename = f"D:\\sina_stock_{stock_code}_page_{page}.html"
write_page(html, filename)
time.sleep(1)
- 功能:爬取页面内容并保存到本地文件。
- 参数:
stock_code
表示股票代码,begin
和end
表示起始页和结束页。 - 细节:
- 构建基本 URL,其中包含股票代码的占位符。
- 遍历起始页到结束页的每一页:
- 构建当前页的 URL。
- 打印正在爬取的 URL。
- 调用
load_page
函数加载当前页的内容。 - 调用
parse_page
函数解析当前页的内容。 - 构建保存当前页内容的文件名。
- 调用
write_page
函数将当前页的内容写入文件。 - 每次请求间隔 1 秒,以避免过快地向服务器发送请求。
主程序入口
if __name__ == "__main__":
stock_code = input("请输入股票代码(如sh000300): ")
begin = input("请输入起始页码:")
end = input("请输入结束页码:")
sina_stock_spider(stock_code, begin, end)
- 功能:提示用户输入股票代码、起始页和结束页,并调用
sina_stock_spider
函数开始爬取操作。