记一次手写python爬虫的经历

前几日,一位朋友在用python写爬虫的时候遇到问题,向我咨询。然而我python几乎连门都没有入,水平就停留在这篇文章的程度上。但是受人所托,并且看起来问题也不难,于是不得已为之,花了大半个晚上才解决。(毕竟我菜)

问题是这样的,想要获取http://www.feixiaohao.com/currencies/这个网站的虚拟货币类型,价格,成交额,涨幅等数据,按理是很简单的。但是据朋友说,使用Beautifulsoup进行分析的时候,发现爬不到这些数据。

我的第一反应就是,这个网站页面怕是用js动态加载的吧,所以html里没有具体内容。但是当我打了log看了一下之后,发现的确能够返回数据。但是用Beautifulsoup处理的时候,却是返回的空。

于是使用python请求网页数据,并保存在本地,仔细研究了一下,发现网页的内容是这样的:
一个表格数据

可以看到,这个表格的<tr>标签是没有对应的</tr>的。虽然据说Beautifulsoup可以自动修复这类问题,不过我好像没有找到具体的方法。而使用Chrome等浏览器打开这个网页查看源码,发现标签被补全了。
浏览器查看网页源码

看来是浏览器自动给没有成对的标签补全了;当然也可能是网站方面故意这么写的,然后用js给补全,但我觉得这没什么意义;理应是浏览器的功劳。既然这样,Beautifulsoup由于网页内容的格式问题不能解析,那么摆在我面前的大概有两条路,其一是用代码把未成对的标签补齐,其二是直接把网页内容当成字符串来分析。

为了省时间,我选择了后者。

接下来的事情就很简单了,小学生都能做的找规律。稍作分析,我发现了每种虚拟币表格项都是以<tr id=开头的,并且其他地方没有这种形式的内容。而每个行表格中,又有若干个<td>标签,依次是序号,币的名称,流通市值,价格,流通数量,成交额(24h),涨幅(24h),价格趋势(7d)。

首先获取网页内容:

request = urllib.request.Request("http://www.feixiaohao.com/currencies/")
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')

然后把包含了所有币种的表格项这部分的html截取下来:

start_index = content.find('<tr id=')
end_index = content.find('</table>')
content = content[start_index:end_index]

现在,我们的content保存的就是所有币种的表格项了。接下来,我们建立一个列表,把每个币种的起始位置保存下来。

list_of_coin_table_start_index = []

start_index = content.find('<tr id=')
while start_index != -1:
    list_of_coin_table_start_index.append(start_index)
    start_index = content.find('<tr id=', start_index + 1)

这样一来,我们就可以对每种虚拟币进行分析了。例如获取这个币的id字段,因为每个表格项都是以<tr id=开头,比如<tr id=bitcoin>,接下来就是id和>,那么就可以截取<tr id=>之间的字符串,即是这个币的id了:

for i in range(0, len(list_of_coin_table_start_index)):
    start_index = list_of_coin_table_start_index[i]
    coin = Coin()

    coin.id = content[start_index + 7:content.find('>', start_index)]

    coins.append(coin)

其他字段同理。最后,我们把分析结果保存在txt里(真的不会数据库):

with open('result.txt', encoding='utf-8', mode='w') as f:
    f.write('id                  名称                  价格                  涨幅\n')
    for c in coins:
        line = ''
        line += c.id
        line += ' ' * (20 - len(c.id))
        line += c.coin_name
        line += ' ' * (22 - len(c.coin_name))
        line += c.price
        line += ' ' * (22 - len(c.price))
        line += c.change
        line += ' ' * (22 - len(c.change))
        line += '\n'
        f.write(line)

txt结果如下(由于时间关系,只截取了id,因为其他字段都是类似的)
结果

算是功德圆满了吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值