Python系列之七_抓知乎收藏夹

  Python系列之七_抓知乎收藏夹


  当我们在知乎上看到一个有趣的收藏夹时,想把里面所有的内容都抓下来,这时我们可以写一个Python程序。



  

  我们发现知乎收藏夹的URL是有规律的:https://www.zhihu.com/collection/27109279?page=1

  下一页page就等于2,依次递增,这个收藏夹共有77页。


  首先我们的思路就是把每一页的HTML源代码先抓下来,然后把该页中的问题和答案都找出来。

  通过查看HTML代码,我们发现问题部分的HTML代码长这样:

<h2 class="zm-item-title"><a target="_blank" href="/question/38627388">开车的人和不开车的人思维有什么区别?</a></h2>


  而答案部分的HTML长这样:

<div class="zm-item-rich-text expandable js-collapse-body" data-resourceid="7658289" data-action="/answer/content" data-author-name="泰姆雷" data-entry-url="/question/38627388/answer/124188978">

<textarea hidden class="content">开车之后明白了一个道理:你能横穿马路跑过去,不是因为你跑得快,而是过来的车都踩了刹车。</textarea>


<div class="zh-summary summary clearfix">

开车之后明白了一个道理:你能横穿马路跑过去,不是因为你跑得快,而是过来的车都踩了刹车。

<a href="/question/38627388/answer/124188978" class="toggle-expand">显示全部</a>

</div>

  答案部分有两处都包含了答案,但经过仔细观察,有一处是完整的答案,放在一个textarea中,平时是隐藏的;另一处只显示了答案的一部分,只有点击“显示全部”时,才显示完整答案。

  因此我们理因选择完整答案,即textarea中的内容。


  可以采用BeautifulSoup的select()功能,该功能可以按照指定规则从HTML代码中找出符合规则的所有标签,返回的一个列表。

  例如:

soup = BeautifulSoup(html);
list1 = soup.select('a');  # 这是标签选择器,可以按照标签名称来选择
list2 = soup.select('.red');  # 这是类选择器,可以按照类名称来选择
list3 = soup.select('#div1');  # 这是ID选择器,可以按照ID来选择
list4 = soup.select('p.red');  # 组合应用
list5 = soup.select('p > a');  # p标签包含下级a标签
  总之,select()选择器非常像CSS中的样式选择器,有标签选择器、类选择器、ID选择器等。


  分析一下,怎么找出所有的问题呢?

<h2 class="zm-item-title"><a target="_blank" href="/question/38627388">开车的人和不开车的人思维有什么区别?</a></h2>

  应该这么写:list1 = soup.select('h2.zm-item-title > a');


  怎么找出所有的答案呢?

<textarea hidden class="content">开车之后明白了一个道理:你能横穿马路跑过去,不是因为你跑得快,而是过来的车都踩了刹车。</textarea>

  应该这么写:list2 = soup.select('textarea.content');


  当取得一页上的问题和答案列表后,只要依次将它们写到一个文本文件中即可。


  我还给问题编了序号,最后是完整代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib
from bs4 import BeautifulSoup
# 为了解决向文本文件中写入中文内容报错,需导入这个库
import sys

# 以下两句是为了解决向文本文件中写入中文内容报错而加的
reload(sys)
sys.setdefaultencoding('UTF-8')

# 打开文件
f = open('E:/tmp/file.txt', 'w')
n = 1  # 问题序号
for page_no in range(1, 77):
    url = 'https://www.zhihu.com/collection/27109279?page=%d' % page_no
    page = urllib.urlopen(url)
    soup = BeautifulSoup(page)
    questions = soup.select('h2.zm-item-title > a')
    answers = soup.select('textarea.content')
    for i in range(len(questions)):
        f.write('\n%d. %s\n' % (n, questions[i].string))
        f.write('答:%s\n' % answers[i].string)
        n += 1
f.close()


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值