金融数据分析(Python)个人学习笔记(12):网络爬虫

一、导入模块和函数

from bs4 import BeautifulSoup
from urllib.request import urlopen
import re
from urllib.error import HTTPError
from time import time

bs4:用于解析HTML和XML文档的Python库。
BeautifulSoup:方便地从网页内容中提取和处理数据,比如查找特定的标签、获取标签的属性和文本内容。
urllib:用于处理URL相关的操作以及进行网络请求
urllib.request:用于打开和读取URL(Uniform Resource Locator,统一资源定位符)的模块
urllib.error:用于处理网络请求错误的模块。
HTTPError:当在使用urlopen等函数进行网络请求时,如果遇到HTTP错误(例如404页面未找到、500服务器内部错误等),就会抛出HTTPError异常。通过捕获这个异常,可以对错误情况进行处理。
urlopen:接受一个URL作为参数,打开指定的URL并返回一个表示该URL内容的对象,通过这个对象可以读取网页的内容。
re:正则表达式模块。
正则表达式是一种强大的文本模式匹配工具,可以用于在文本中查找、替换、验证等操作。在网络数据抓取中,正则表达式常用于从网页内容中提取符合特定模式的信息。
time:提供了处理时间相关的功能。
time函数:返回当前时间的时间戳(从 1970 年 1 月 1 日 00:00:00 UTC 到现在的秒数)。

二、定义一个获取网页所有同类型连接的函数

def GetLinks(arturl):
    try:
        html = urlopen(arturl)
    except HTTPError as e:
        return []
    bsObj = BeautifulSoup(html)
    return bsObj.find_all("a",{"href": re.compile(r"http:\/\/finance\.sina\.com\.cn.*\.shtml")})
'''
urlopen:打开arturl对应的网页,并将返回的响应对象赋值给变量html
	如果该网站异常404或者网站错误,则抛出“HTTPError”
	如果在打开网页过程中出现HTTPError异常,说明网页访问失败,此时函数将返回一个空列表
BeautifulSoup:对html响应对象中的网页内容进行解析,将解析结果存储在bsObj变量中
	没有指定解析器,默认会使用Python内置的解析器
re.compile:编译正则表达式
	匹配以http://finance.sina.com.cn开头,中间可以是任意字符,最后以.shtml结尾的字符串
find_all:在解析后的网页内容中查找所有<a>标签,并且这些<a>标签的href属性值要符合上述正则表达式。
	最后将找到的所有<a>标签组成的列表作为函数的返回值。
	如果查找的属性不存在,则返回空置[]
r"http:\/\/finance\....":
	在正则表达式字符串前面加上r,这样字符串里的反斜杠就不会被当作转义字符处理。
	否则会报出警告
'''

三、定义获取新闻标题、时间、正文的函数

def GetTitle(arturl):
    try:
        html = urlopen(arturl)
    except HTTPError as e:
        return []
    try:
        bs = BeautifulSoup(html)
        mytitle = bs.h1.get_text()
    except AttributeError as e:
        return []
    return mytitle
'''
bs.h1.get_text():尝试从解析后的网页内容中获取<h1>标签,并提取其内部的文本内容,将其赋值给变量mytitle。
	如果网站不存在相应标签,则返回None,通过None调用函数,返回AttributeError
'''
def GetDate(arturl):
    try:
        html = urlopen(arturl)
    except HTTPError as e:
        return []
    bs = BeautifulSoup(html)
    md = bs.findAll(class_ = 'date')
# 如果网站不存在相应属性值,则返回[],通过[]调用函数,返回AttributeError
    if md == []:
        return []
    else:
        mydate = md[0].get_text()
# 若md不为空列表,提取列表中第一个元素的文本内容,并将其赋值给变量mydate
    return mydate
def GetArticle(arturl):
    try:
        html = urlopen(arturl)
    except HTTPError as e:
        return []
    bs = BeautifulSoup(html)
    ma = bs.findAll(class_ = 'article')
# 如果网站不存在相应属性值,则返回[],通过[]调用函数,返回AttributeError
    if ma == []:
        return []
    else:
        myarticle = ma[0].get_text()
    return ''.join(myarticle.split())
'''
split():当不传入任何参数时,以空白字符(如空格、制表符、换行符等)为分隔符,将myarticle分割成一个字符串列表
join():将一个可迭代对象(如列表、元组等)中的元素连接成一个字符串。
	调用该方法的字符串对象会作为连接元素之间的分隔符。
'''

四、采集6月1日至6月3日所有相关网页

from datetime import datetime

# 是否在6月1日至6月3日之间
def isrightdate(arturl):
    dat = GetDate(arturl)
    if dat == []:
        return False
    else:
        dat1 = dat[:4] + '-' + dat[5:7] + '-' +dat[8:10] # 转换为YYYY-MM-DD
        aft = (datetime.strptime(dat1,'%Y-%m-%d') - datetime.strptime('2022-06-01','%Y-%m-%d')).days >=0 # 判断提取的日期是否在2022年6月1日之后,计算两个日期之间的天数差
        bef = (datetime.strptime('2022-06-03','%Y-%m-%d') - datetime.strptime(dat1,'%Y-%m-%d')).days >=0 # 判断提取的日期是否在2022年6月3日之前
        return aft and bef
'''
GetDate:从指定网页中提取日期信息,将结果存储在变量dat中
datetime.strptime:将日期字符串转换为 datetime 对象
'''

定义一个名为GetAllLinks的递归函数,用于从给定的网页链接列表arturls开始,递归地查找所有符合日期要求的新浪财经网页链接,并将这些链接存储在全局变量alllinks中,同时避免重复添加链接。

alllinks = []
def GetAllLinks(arturls): # 输入变量为list
    if arturls == []:
        return # 函数中无论return位置在哪,即使在for循环中,都结束函数
    global alllinks
    urls = []
    for arturl in arturls:
        links = GetLinks(arturl)
        for link in links:
            if isrightdate(link.attrs["href"]): # 时间是否准确
                if link.attrs["href"] is not None: # 是否有链接属性
                    if link.attrs["href"] not in alllinks: # 排除重复网页
                        urls.append(link.attrs["href"])
                        alllinks.append(link.attrs["href"])
                        print(link.attrs["href"])
    print('搜索完一层')
    GetAllLinks(urls)
'''
global alllinks:声明要使用全局变量alllinks,以便在函数内部对其进行修改
link.attrs["href"]:检查链接是否有href属性,避免处理没有链接的元素
	link:BeautifulSoup解析HTML文档后得到的<a>标签对象
	attrs:BeautifulSoup中标签对象的一个属性,它是一个字典,包含了该标签的所有属性及其对应的值
	["href"]:字典的索引操作
'''

测量GetAllLinks函数的执行时间

start = time() # 当前时间戳
arturl = ["https://finance.sina.com.cn/wm/2022-06-03/doc-imizmscu4879155.shtml"]
# 定义起始链接列表,输入变量为list
GetAllLinks(arturl)
print('\n用时:\n', time()-start) # \n:换行符

五、将新闻标题、时间、网址 保存至CSV文件

import csv

filename = 'my_sinanews1.csv'
csvFile = open(filename, 'w+', encoding = 'utf-8', newline = '')
# newline='':避免在写入 CSV 文件时出现多余的空行

try:
    writer = csv.writer(csvFile)
    writer.writerow(('Num', 'Title', 'Date', 'html', 'Article')) # 写入表头
    # writerow:写入信息
    i = 1 # 初始编号
    for link in alllinks:
        writer.writerrow((i,GetTitle(link),GetDate(link),link,GetArticle(link)))
        # 将一行数据写入 CSV 文件,数据包含编号、标题、日期、链接和文章内容
        i = i + 1
finally:
    csvFile.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值