简介
爬取知乎专栏文章
皇太极在纽约
皇太极在纽约是我非常喜欢的知乎答主,他写的文章,回答鲜有灌水,其前几个月硬刚拼多多受到威胁一事还上了热搜。
这次来爬取他的知乎专栏
参考
参考了几个b站爬虫视频,受用深刻
av11371375
av50840168
av81903343
av45382106
分析
知乎的特点是其内容都是动态加载的,效果就是鼠标滚轮向下滚动会滚不到底,侧边按钮会不断向上。参照(av11371375)
同时,F12控制台和网页源代码发现,网页源代码的url好像找不到,有缺失,因为控制台显示的都是经过渲染过后的网页。
-
通过F12刷新抓包
Network->XHR->Headers
查询Json语句
滚轮向下滚动左侧便会不断更新,查看请求头(Headers),发现
网页一共8页,每页10篇文章
Headers
同时 ,每个响应的Requests url仅仅在最后的offset不同
第一页.png
i第二页.png
因此便可以得到每页的url
- response便可以看到json代码
可以放到json.cn解析
response
-解析
image.png
image.png
解析json代码后,就可以看到zhuanlan的url
代码
载入库
import urllib
import requests
from bs4 import BeautifulSoup
import re
import json
import pprint #用于美化打印,解析json后用来打印非常直观,简便
get_urls函数
#参数m为页数
def get_url(m):
urls=['https://zhuanlan.zhihu.com/api/columns/daojianghu/articles?include=data%5B%2A%5D.admin_closed_comment%2Ccomment_count%2Csuggest_edit%2Cis_title_image_full_screen%2Ccan_comment%2Cupvoted_followees%2Ccan_open_tipjar%2Ccan_tip%2Cvoteup_count%2Cvoting%2Ctopics%2Creview_info%2Cauthor.is_following%2Cis_labeled%2Clabel_info&limit=10&offset={}' .format(i) for i in range(0,(m*10),10)]
return urls
爬取函数
#x为指针,用于标记打印了多少
def get_ZhiHu_Text(urls,x):
r_urls=requests.get(urls,headers=headers).text
data_ZhuanLan=json.loads(r_urls)
#json.loads就相当于前面的json.cn,用于解析json代码,
#解析后,可以用import的pprint.pprint打印(详见av45382106)
ZhuanLan_url={}
for i in data_ZhuanLan['data']:
ZhuanLan_url[i['title']]=i['url']
r = requests.get(i['url'], headers=headers).text
pages_soup = BeautifulSoup(r,'html.parser')
#使用beautifulsoup解析'html.parser'为解析器
pages_text=pages_soup.find_all(attrs={'class':'RichText ztext Post-RichText'})
#使用find_all函数可以找到所有的class为RichText ztext Post-RichText'的div
#注意findall函数参数不能直接查class,要嵌套在attrs,class为属性
print(i['title'], end="")
#打印文章标题
for n in pages_text:
text = n.get_text()
#得到网页的所有的文本
text = text.replace('\xa0', ' ')
try:
file = open('Huang_taiji/' + i['title'] + '.txt', 'wb+')
file.write(bytes(text, encoding="utf8"))
#写入保存
print('-----------完成,序号:' + str(x))
#print('-----------完成')
except:
file = open('text/' + str(x) + '.txt', 'wb+')
file.write(bytes(text, encoding="utf8"))
print('-----------完成,序号:' + str(x))
#print('-----------完成')
x+=1
file.close()
return x
主函数
if __name__=='__main__':
x = 1
urls=get_url(8 )
#打印8页
x = get_ZhiHu_Text(urls[0], x)
for i in range(0,len(urls)):
x = get_ZhiHu_Text(urls[i], x)
print('第'+str(i+1)+'页已打印')