自编一个从指定位置开始查找字符串的Python代码

原创于2022/10/24。修改:2022/11/5。

在用Python爬网页抓取文字时有各种方法:BeautifulSoup、xpath、find_element、re正则表达式等。如何实现从一个指定的位置开始查找,需要花时间琢磨代码。我从中国银行最新汇率的网页爬汇率数据来练手,思路很简单,先找到页面中的美元,然后从美元这个位置开始找旁边的汇率数据。

  

各位大佬看到这里可能会说,这超级简单啊,上面的BeautifulSoup、xpath、find_element随便一个都能拿下来。别人造好的车轮都有得卖,为什么还要自己造一个?但是我的目的是不借助其它库的函数,只用Python自带的find来实现,重新造一个适合自己用的代码,如果编译成exe也可尽量缩小exe的大小。

import requests
 
def my_find(string,from_where,start_str,end_str):
    # 参数说明:
    # string:源字符串
    # from_where:从哪里开始找,类型可以是字符串,也可以是整数(整数意味着具体位置)
    # start_str:要找的关键词的开头
    # end_str:要找的关键词的结尾
    t1=string.find(from_where)+len(from_where) if type(from_where)==str else from_where
    t2=string.find(start_str,t1)+len(start_str)
    t3=string.find(end_str,t2)
    if t1==-1 or t2==-1 or t3==-1:
        return ''
    else:
        return string[t2:t3],t3+len(end_str) # 返回字符串以及最后一次查找的位置
        
url='https://www.boc.cn/sourcedb/whpj/'
headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',}
res=requests.get(url,headers=headers)
res.encoding='utf-8'
res=res.text
print('今天汇率:\n币种\t现汇买入价\t现钞买入价\t现汇卖出价\t现钞卖出价\t中行折算价\n'+'-'*85)
for i in ['美元','港币','欧元','英镑','卢布','日元']:
    # 第一次找指定币种旁边的汇率数据
    my_str=my_find(res,"<td>"+i+"</td>","<td>","</td>")
    # 返回的结果类型是元组,元素分别是汇率数据、查找的位置
    # 先输出第一个汇率数据,my_str后面要有[0]
    print(i+':\t'+my_str[0],end='\t\t')
    # 然后从上一次查找的位置顺着查找同一行其他四列的汇率数据
    # 这时my_find函数第二个参数my_str[1]是上一次查找的位置
    for j in range(4):
        my_str=my_find(res,my_str[1],"<td>","</td>")
        print(my_str[0],end='\t\t')
    print()

上述my_find函数代码中的t1、t2、t3图解

运行结果截图(注:下面截图是2022/11/5的汇率数据,上面截图中的汇率数据是2022/10/24):

以上是我自己造的“车轮”。下面示范一下用现成的“车轮”(比如xpath)来查找文字,首先查找汇率页面中的“美元”,定好位再顺藤摸瓜找下一级数据,代码为:

# 定位td标签内容中含有“美元”的标签
//td[contains(text(),"美元")]
# 从含有“美元”字样的下一级td标签抓取文字
//td[contains(text(),"美元")]/following-sibling::td[1]/text()

xpath需要先从lxml库引入etree:from lxml import etree。

import requests
from lxml import etree

url='https://www.boc.cn/sourcedb/whpj/'
headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',}
res=requests.get(url,headers=headers)
res.encoding='utf-8'
res=res.text
html=etree.HTML(res)
print('今天汇率:\n币种\t现汇买入价\t现钞买入价\t现汇卖出价\t现钞卖出价\t中行折算价\n'+'-'*85)
for i in ['美元','港币','欧元','英镑','卢布','日元']:
    print(i+':',end='\t')
    for j in range(1,6):
        print(html.xpath('//td[contains(text(),"'+i+'")]/following-sibling::td['+str(j)+']/text()')[0],end='\t\t')
    print()

使用xpath做匹配字符串的表达式晦涩难懂,需要多花时间理解。例一代码的my_find()是自己写的,容易理解,只是在某些复杂情况下可能不奏效。

我将以上两个例子的代码分别编译成exe文件(在虚拟环境中编译,以求最小的exe体积),exe体积分别是:

例一(自编函数):    7.03MB

例二(引入lxml库):  9.43MB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值