美文网首页
爬虫精进(六) ------ 项目实操

爬虫精进(六) ------ 项目实操

作者: 千喜Ya | 来源:发表于2019-07-25 10:45 被阅读0次
知识地图

一.项目分析

爬取知乎大v张佳玮的文章“标题”、“摘要”、“链接”,并存储到本地文件。

1.查看爬取信息是否存在HTML页面里面

张佳玮的知乎文章URL在这里:https://www.zhihu.com/people/zhang-jia-wei/posts?page=1
点击右键——检查——Network,选All(而非XHR),然后刷新网页,点进去第0个请求:posts_by_votes,点Preview


发现有文章标题,看来数据是放在HTML里。那么,走的应该是【知识地图】里上面那条路径
2.编写代码

那好,就可以去观察一下网页源代码了,点回Elements。分析根据哪个标签获取
获取标题文章 :

import requests
from bs4 import BeautifulSoup
#引入request和bs
url='https://www.zhihu.com/people/zhang-jia-wei/posts/posts_by_votes?page=1'
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
#使用headers是一种默认的习惯,默认你已经掌握啦~
res=requests.get(url,headers=headers)
#发起请求,将响应的结果赋值给变量res。
print(res.status_code)
#检查状态码 
bstitle=BeautifulSoup(res.text,'html.parser')
#用bs进行解析
title=bstitle.findAll(class_='ContentItem-title')
#提取我们想要的标签和里面的内容
print(title)
#打印title

会发现只有两个标题,先来做个排查,使用 res.text 打印一下网页源代码。会发现第一页的最后一篇文章的标题“出走半生,关山万里,归来仍是少女心气”在这个网页源代码里面搜索是搜不到的,那么重新开始分析

3.重新分析XHR

打开Network,点开XHR,同时刷新页面,看到出现了很多个请求。
浏览一下,看到两个带articles的请求,感觉有戏。点开首个articles看看preview,一层层点开,看到“title:记住就是一切”,猜测这是一个文章标题。
在网页里面用command+f(windows电脑用ctrl+f)搜索一下“记住就是一切”,发现搜不到,奇怪。
那就看看跟首个articles请求长得很像的另一个articles的请求好啦,仍然看preview,看到title: "国产航母下水……让我想到李鸿章和北洋舰队",仍然在网页里搜一下:



果然在这里。看来这个articles的请求里面存的是第一页的文章标题。这下妥了,我们知道向哪个url获取数据了。
那首个带articles的请求是什么?其实这是知乎的网站设计,当你刷新第一页的时候,默认你也请求了第二页的文章数据,这样你加载就会比较流畅。
现在,理论上我们可以拿到第一页的文章数据了,那如果要拿到之后所有页面的数据,还不够吧。
好,我们去观察第1页对第2页的请求,和第2页里对第3页请求的参数区别,是在headers里面的query string parameters里面。




然后发现除了offset都一样,offset代表起始值,limit表示加载的限制数,通过循环我们是可以爬到所有页数的内容了。

我们的大致思路也就出来了:


4.拿到前3页的数据
import requests
from bs4 import BeautifulSoup
import  csv

articleInfo = []
url = 'https://www.zhihu.com/api/v4/members/zhang-jia-wei/articles'
for i in range(3):
    params = {
    'include' : 'data[*].comment_count,suggest_edit,is_normal,thumbnail_extra_info,thumbnail,can_comment,comment_permission,admin_closed_comment,content,voteup_count,created,updated,upvoted_followees,voting,review_info,is_labeled,label_info;data[*].author.badge[?(type=best_answerer)].topic',
    'offset' : str(i*20),
    'limit' : '20',
    'sort_by' : 'voteups'
    }
    header = {
        'referer' : 'https://www.zhihu.com/people/zhang-jia-wei/posts/posts_by_votes?page=' + str(i),
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
    }
    res = requests.get(url,params=params,headers = header)
    article = res.json()
    for oneArticle in article['data']:
        articleInfo.append([oneArticle['title'],oneArticle['excerpt'],oneArticle['url']])

print(articleInfo)

那么如何能判断是否是最后一页了呢
第一页和最后一页请求的参数区别:




对比一下,你会发第一页的is_end是显示false,最后一页的is_end是显示true,这个元素可以帮我们结束循环。
至于那个totals: 919元素,我算了一下页码和每页的文章数,判断这是文章的总数,也同样可以作为结束循环的条件。两个元素都可以用,在这里我们用is_end元素。
所以最终代码为 :

import requests
from bs4 import BeautifulSoup
import  csv

articleInfo = []
url = 'https://www.zhihu.com/api/v4/members/zhang-jia-wei/articles'
i = 0
file=open("article.csv",'w',newline='')
writer = csv.writer(file)
while True:
    params = {
    'include' : 'data[*].comment_count,suggest_edit,is_normal,thumbnail_extra_info,thumbnail,can_comment,comment_permission,admin_closed_comment,content,voteup_count,created,updated,upvoted_followees,voting,review_info,is_labeled,label_info;data[*].author.badge[?(type=best_answerer)].topic',
    'offset' : str(i*20),
    'limit' : '20',
    'sort_by' : 'voteups'
    }
    header = {
        'referer' : 'https://www.zhihu.com/people/zhang-jia-wei/posts/posts_by_votes?page=' + str(i),
        'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
    }
    res = requests.get(url,params=params,headers = header)
    article = res.json()
    for oneArticle in article['data']:
        articleInfo.append([oneArticle['title'],oneArticle['excerpt'],oneArticle['url']])
        writer.writerow([oneArticle['title'],oneArticle['excerpt'],oneArticle['url']])
    print(str(i) + " " + str(article['paging']['is_end']))
    if article['paging']['is_end']:
        break;
    i += 1
file.close()
print(articleInfo)

相关文章

  • 爬虫精进(六) ------ 项目实操

    一.项目分析 爬取知乎大v张佳玮的文章“标题”、“摘要”、“链接”,并存储到本地文件。 1.查看爬取信息是否存在H...

  • 增长裂变精进社+第一周+C队+Z'zzzzzzzzy

    https://shimo.im/docs/LQvPzkKLoTgYVknX/ 《精进社实操项目活动方案SOP-周...

  • Ajax异步加载:运用requests、BeautifulSou

    第二篇爬虫项目实操:运用requests库、BeautifulSoup库爬取简书专题 ---- “数据蛙每周交作业...

  • 项目实操

    一、原型 1.给所有相关人员演示(否则需求理解错误) 2.加交互(真实感强,不容易漏掉页面逻辑,容易理解) axu...

  • 增长裂变精进社+第一周+C队+药片三叶

    https://shimo.im/docs/7kMvjcwd21Q3SO4C/ 点击链接查看「精进社实操项目活动方...

  • 实操六

    知识点范围:集合与IO流 一、选择题 以下选项中关于Java集合的说法错误的是( AC )。(选择2项) A:...

  • SEO实操手册|六、网络爬虫(蜘蛛)

    本章主要介绍SEO优化工作中,在网络爬虫方面需要了解的工作。本文版权由“ 北朔潜龙 ”所有,仅供学习使用,请勿转载...

  • Java网络爬虫实操(2)

    上一篇: Java网络爬虫实操(1) 本篇文章继续介绍爬虫框架NetDiscovery的使用:如何发重复请求、如何...

  • Mybatis-2-2.实操总结

    通过上一部分的实操知道了Mybatis的用法。那么这章总结一下上一个实操项目。 实操项目全部源代码:https:/...

  • python简单爬虫实操

    2019年底看完谢春花的《2020,请对我好一点》的演唱会,发现2020开头并没有那么顺利,面试终面没过,其他机会...

网友评论

      本文标题:爬虫精进(六) ------ 项目实操

      本文链接:https://www.haomeiwen.com/subject/trsfrctx.html