Python3从零开始爬取今日头条的新闻【一、开发环境搭建】

Python3从零开始爬取今日头条的新闻【二、首页热点新闻抓取】

Python3从零开始爬取今日头条的新闻【三、滚动到底自动加载】

Python3从零开始爬取今日头条的新闻【四、模拟点击切换tab标签获取内容】

Python3从零开始爬取今日头条的新闻【五、解析头条视频真实播放地址并自动下载】

所谓爬虫,就是通过编程的方式自动从网络上获取自己所需的资源,比如文章、图片、音乐、视频等多媒体资源。通过一定的方式获取到html的内容,再通过各种手段分析得到自己所需的内容,比如通过BeautifulSoup对网页内容进行解析提取。

本文通过selenium的webdriver模拟浏览器来浏览网页,通过lxml库解析得到咱所需的内容。下面开始我们的爬虫工作。

1.头条首页内容分析

我们今天的目标是提取头条中间区域的要闻内容:标题、图片、作者、类型、发布时间

首先,我们分析一下头条新闻页面的内容,用火狐浏览器打开头条首页,查看中间区域的热文内容

如上图所示,我们要抓取首页热文的中间区域新闻,一共有4种类型:

  • ① 视频类型 → 左侧有图片,右侧是标题,点击可播放
  • ②③ 纯文本类型 → 左侧没图片,中间是标题
  • ④ 图文类型 → 左侧有图片,右侧是标题
  • ⑤ 多图类型 → 上面是标题,下面是多张图片罗列
  • 如果要抓取其它类型 ,原理也是一样的,万变不离其宗~

看上图右侧的dom元素结构,可以看出来,中间区域的每一条热文,都是在li标签包着的,而所有的li标签都是ul的子元素。

① 视频类型的html内容

  1. <li class="">
  2. <div getuser-info-url="/user/info/" class="bui-box video-mode">
  3. <div class="bui-left video-mode-lbox">
  4. <div style="width: 325px; height: 183px;" class="player mini-btn-visible transitionable" oncontextmenu="return false">
  5. <div class="before"><img lazy="loaded" src="//p3.pstatp.com/list/300x170/pgc-image/1537883970674d7092c5d6d"
  6. alt=""> <span class="play-btn"><i style="font-size: 30px; color: rgb(255, 255, 255);" class="bui-icon icon-playvedio"></i></span>
  7. <span class="duration"><i style="font-size: 8px;" class="bui-icon icon-playvedio"></i><em>00:33</em></span></div>
  8. <div class="player-wrap">
  9. <div class="player-inner" id="tt_video_17330"></div>
  10. <div class="action-line"><i style="font-size: 18px;" class="bui-icon icon-close_small"></i> <span>按住该区域可拖动小窗</span></div>
  11. </div>
  12. <div style="display: none;" class="next">
  13. <div style="display: none;" class="next-one">
  14. <p class="info">接下来播放</p>
  15. <h3 class="title"></h3> <i><img alt="" src="" height="78" width="78"></i>
  16. <div><i class="cancel">取消播放</i></div>
  17. </div>
  18. <div style="display: none;" class="next-list">
  19. <ul></ul>
  20. <div class="replay-wrap"><i class="replay">重播</i></div>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="video-mode-rbox">
  26. <div class="title-box" ga_event="video_title_click"><a class="link" target="_blank" href="/group/6605161411674898947/">「独家V观」习近平在黑龙江考察
  27. 首站来到建三江</a></div>
  28. <div class="bui-box footer-bar"><a class="footer-bar-action media-avatar" ga_event="video_avatar_click"
  29. target="_blank" href="/c/user/96888584941/"><img lazy="loaded" src="//p3.pstatp.com/large/6ee500006a1b9c777420"></a>
  30. <a class="footer-bar-action source" ga_event="video_name_click" target="_blank" href="/c/user/96888584941/">央视新闻移动网</a>
  31. <span class="footer-bar-action"></span> <a class="footer-bar-action source" ga_event="video_frequency_click"
  32. target="_blank" href="/group/6605161411674898947/">7238次播放</a></div>
  33. <div class="action-dislike" ga_event="dislike_click"><i style="font-size: 16px; color: rgb(221, 221, 221);"
  34. class="bui-icon icon-close_small"></i>
  35. 不感兴趣
  36. </div>
  37. </div>
  38. </div>
  39. </li>

从dom元素结构可以看到我们所需的标题、图片、类型等内容

②③ 纯文本类型的html内容

  1. <li class="">
  2. <div class="no-mode" ga_event="article_item_click">
  3. <div class="title-box" ga_event="article_title_click"><a class="link" target="_blank" href="/group/6605095646191944196/">国家主席习近平任免驻外大使</a></div>
  4. <div class="bui-box footer-bar">
  5. <div class="bui-left footer-bar-left"><a class="footer-bar-action tag tag-style-other" ga_event="article_tag_click"
  6. target="_blank" href="search/?keyword=%E6%97%B6%E6%94%BF">时政</a> <a class="footer-bar-action media-avatar"
  7. ga_event="article_avatar_click" target="_blank" href="/c/user/4377795668/"><img lazy="loaded" src="//p2.pstatp.com/large/3658/7378365093"></a>
  8. <a class="footer-bar-action source" ga_event="article_name_click" target="_blank" href="/c/user/4377795668/">&nbsp;新华网&nbsp;⋅</a>
  9. <a class="footer-bar-action source" ga_event="article_comment_click" target="_blank" href="/group/6605095646191944196//#comment_area">&nbsp;52评论&nbsp;⋅</a>
  10. <span class="footer-bar-action">&nbsp;38分钟前</span>
  11. <!---->
  12. <!---->
  13. <!---->
  14. </div>
  15. <div class="bui-right">
  16. <div dislikeurl="/api/dislike/" class="action-dislike" ga_event="dislike_click"><i style="font-size: 16px; color: rgb(221, 221, 221);"
  17. class="bui-icon icon-close_small"></i>
  18. 不感兴趣
  19. </div>
  20. </div>
  21. </div>
  22. </div>
  23. </li>

④ 图文类型的html内容

  1. <li class="">
  2. <div class="bui-box single-mode" ga_event="article_item_click">
  3. <div class="bui-left single-mode-lbox" ga_event="article_img_click"><a class="img-wrap" target="_blank" href="/group/6605101139232817678/"><img
  4. lazy="loaded" src="//p98.pstatp.com/list/190x124/pgc-image/15378695822600023b5e56b" class="lazy-load-img">
  5. <!----></a></div>
  6. <div class="single-mode-rbox">
  7. <div class="single-mode-rbox-inner">
  8. <div class="title-box" ga_event="article_title_click"><a class="link" target="_blank" href="/group/6605101139232817678/">一旦爆发冲突,美国航母被击沉损失有多大?兰德公司公布答案</a></div>
  9. <div class="bui-box footer-bar">
  10. <div class="bui-left footer-bar-left"><a class="footer-bar-action tag tag-style-other" ga_event="article_tag_click"
  11. target="_blank" href="news_military">军事</a> <a class="footer-bar-action media-avatar"
  12. ga_event="article_avatar_click" target="_blank" href="/c/user/6398208487/"><img lazy="loaded"
  13. src="//p3.pstatp.com/large/78f000a6e8e1a98cf54"></a> <a class="footer-bar-action source"
  14. ga_event="article_name_click" target="_blank" href="/c/user/6398208487/">&nbsp;全球军事热评&nbsp;⋅</a>
  15. <a class="footer-bar-action source" ga_event="article_comment_click" target="_blank" href="/group/6605101139232817678//#comment_area">&nbsp;100评论&nbsp;⋅</a>
  16. <span class="footer-bar-action">&nbsp;41分钟前</span>
  17. <!---->
  18. <!---->
  19. <!---->
  20. </div>
  21. <div class="bui-right">
  22. <div dislikeurl="/api/dislike/" class="action-dislike" ga_event="dislike_click"><i style="font-size: 16px; color: rgb(221, 221, 221);"
  23. class="bui-icon icon-close_small"></i>
  24. 不感兴趣
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </li>

⑤ 多图类型的html内容

  1. <li class="">
  2. <div class="more-mode" ga_event="gallery_item_click">
  3. <div class="title-box" ga_event="gallery_title_click"><a class="link" target="_blank" href="/group/6604959967424283150/">老人带村民历时36年,系绳索悬崖上开凿9公里水渠,几次差点送命</a></div>
  4. <div class="bui-box img-list" ga_event="gallery_img_click"><a class="img-wrap img-item" target="_blank" href="/group/6604959967424283150/"><img
  5. lazy="loaded" src="//p3.pstatp.com/list/190x124/pgc-image/15378317404774aecf17a3c" class="lazy-load-img"></a><a
  6. class="img-wrap img-item" target="_blank" href="/group/6604959967424283150/"><img lazy="loaded" src="//p1.pstatp.com/list/190x124/pgc-image/1537831740473c836263103"
  7. class="lazy-load-img"></a><a class="img-wrap img-item" target="_blank" href="/group/6604959967424283150/"><img
  8. lazy="loaded" src="//p1.pstatp.com/list/190x124/pgc-image/15378326628551660c762d3" class="lazy-load-img"></a><a
  9. class="img-wrap img-item" target="_blank" href="/group/6604959967424283150/"><img lazy="loaded" src="//p9.pstatp.com/list/190x124/pgc-image/1537831741249b93def511b"
  10. class="lazy-load-img"></a>
  11. <!----> <i class="pic-tip"><span>15图</span></i></div>
  12. <div class="bui-box footer-bar">
  13. <div class="bui-left footer-bar-left"><a class="footer-bar-action tag tag-style-society" ga_event="article_tag_click"
  14. target="_blank" href="news_society">社会</a> <a class="footer-bar-action media-avatar" ga_event="gallery_avatar_click"
  15. target="_blank" href="/c/user/5921344817/"><img lazy="loaded" src="//p1.pstatp.com/large/249a0015871d8abbdf27"></a>
  16. <a class="footer-bar-action source" ga_event="gallery_name_click" target="_blank" href="/c/user/5921344817/">&nbsp;乙图&nbsp;⋅</a>
  17. <a class="footer-bar-action source" ga_event="gallery_comment_click" target="_blank" href="/group/6604959967424283150//#comment_area">&nbsp;234评论&nbsp;⋅</a>
  18. <span class="footer-bar-action">&nbsp;2小时前</span>
  19. <!---->
  20. <!---->
  21. <!---->
  22. </div>
  23. <div class="bui-right">
  24. <div dislikeurl="/api/dislike/" class="action-dislike" ga_event="dislike_click"><i style="font-size: 16px; color: rgb(221, 221, 221);"
  25. class="bui-icon icon-close_small"></i>
  26. 不感兴趣
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </li>

从上面四种类型新闻的布局可以看出,每个li标签的class属性都是空的,li的子元素就只有一个子元素div,并且这个div有个ga_event属性,我们分析下各种类型新闻的li的直接子元素的div布局:

1:纯文本类型、图文类型,这个ga_event属性值均为article_item_click,但这两种类型的class属性值不一样,图文类型的是bui-box single-mode,纯文本类型的是no-mode

2:视频类型,没有ga_event属性,有个属性值为==/user/info/的 getuser-info-url属性,而class属性值为bui-box video-mode==

3:多图类型,这个ga_event属性值为gallery_item_click,class属性值为more-mode

所以我们可以根据以上分析的各种类型布局的特点,来找出每一条新闻的元素结构,再通过XPATH定位得到我们所需要的标题、图片、类型、作者、时间等内容。

思路有了,那我们就开搞吧~

2.代码编写

2.1、编写程序主入口代码

我们来看主入口部分代码:

  1. # -*- coding: utf-8 -*-
  2. # 引入模拟浏览器框架支持库
  3. from selenium import webdriver
  4. from selenium.webdriver.chrome.options import Options
  5. from selenium.webdriver.common.keys import Keys
  6. from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
  7. from selenium.webdriver.common.by import By
  8. from selenium.webdriver.support.ui import WebDriverWait
  9. from selenium.webdriver.support import expected_conditions as EC
  10. # 引入ActionChains鼠标操作类支持库
  11. from selenium.webdriver.common.action_chains import ActionChains
  12. # xpath解析支持库
  13. from lxml import etree
  14. # 自定义的新闻结构体
  15. from newsInfo import NewsInfo
  16. # 自定义解析html结构的实现类
  17. from parseNews import PaseNews
  18. class ParseTouTiao(object):
  19. """
  20. 构造函数,初始化资源
  21. """
  22. def __init__(self):
  23. self.__firefox_options = webdriver.FirefoxOptions()
  24. self.__firefox_options.add_argument('--headless')
  25. self.__firefox_options.add_argument('--disable-gpu')
  26. self.__browser = webdriver.Firefox(firefox_options=self.__firefox_options)
  27. """
  28. 获取头条首页内容
  29. """
  30. def __getTouTiaoHtml(self, url):
  31. # 简单的入参校验
  32. if url and '' != url and url.startswith("http"):
  33. # 浏览器打开页面
  34. self.__browser.get(url)
  35. try:
  36. # 此处等到我们所需的热文元素加载出来了再进行下一步,避免页面还没加载完成就去解析内容导致内容为空
  37. element = WebDriverWait(self.__browser, 10).until(
  38. EC.presence_of_element_located((By.XPATH, "//ul/li/div[@ga_event=article_item_click]"))
  39. )
  40. except Exception as ex:
  41. print(ex)
  42. finally:
  43. pass
  44. resHtml = self.__browser.page_source
  45. return resHtml
  46. """
  47. 提取li标签内容
  48. """
  49. def _parseNews(self, url):
  50. resHtml = self.__getTouTiaoHtml(url)
  51. if not resHtml:
  52. print("解析内容出错")
  53. return
  54. # 转换为etree解析模式内容
  55. etree_html = etree.HTML(resHtml)
  56. # 通过前面对每条新闻dom结构分析,由xpath方式提取所有新闻所在的<li>布局
  57. li_elements = etree_html.xpath('//ul[@infinite-scroll-immediate-check][@infinite-scroll-immediate-check-count="containerCheckCount"]/li')
  58. # 解析得到的新闻列表
  59. parseNewsInfo = []
  60. # 新闻解析类
  61. parseNew = PaseNews()
  62. if li_elements and len(li_elements) > 0:
  63. for li in li_elements:
  64. newinf = parseNew.parse(li)
  65. # 省略部分代码......
  66. else:
  67. return
  68. # 省略部分代码......

代码的注释很清楚,简要介绍下几个方法:

2.1.1初始化火狐浏览器插件

  • __init__ 方法:初始化火狐浏览器插件属性,其中下面三行代码设置火狐浏览器调用时,不显示浏览器的界面,如果你想看到浏览器的自动化操作行为,你可以在实例化browser时不传这个self.__firefox_options 参数即可
  1. self.__firefox_options.add_argument('--headless')
  2. self.__firefox_options.add_argument('--disable-gpu')
  3. self.__browser = webdriver.Firefox(firefox_options=self.__firefox_options)

2.1.2获取头条首页html内容

  • __getTouTiaoHtml (self, url) 方法:通过selenium的webdriver调用火狐浏览器打开头条首页,并且等到页面加载出来内容后再进行下一步。
  1. def __getTouTiaoHtml(self, url):
  2. # 简单的入参校验
  3. if url and '' != url and url.startswith("http"):
  4. # 浏览器打开页面
  5. self.__browser.get(url)
  6. try:
  7. # 此处等到我们所需的热文元素加载出来了再进行下一步,避免页面还没加载完成就去解析内容导致内容为空
  8. element = WebDriverWait(self.__browser, 10).until(
  9. EC.presence_of_element_located((By.XPATH, "//ul/li/div[@ga_event=article_item_click]"))
  10. )
  11. except Exception as ex:
  12. print(ex)
  13. finally:
  14. pass
  15. resHtml = self.__browser.page_source
  16. return resHtml

其中通过 WebDriverWait 同步等待的方法来保证页面加载出来我们所需的内容了,再进行下一步。最后返回的内容self.__browser.page_source就是我们下一步分析新闻所需的HTML内容了,形式如下所示:

  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <title>今日头条</title>
  5. <meta http-equiv="x-dns-prefetch-control" content="on">
  6. <meta name="renderer" content="webkit">
  7. <meta name="keywords" content="今日头条,头条,头条网,头条新闻,今日头条官网">
  8. <meta name="description" content="《今日头条》(www.toutiao.com)是一款基于数据挖掘的推荐引擎产品,它为用户推荐有价值的、个性化的信息,提供连接人与信息的新型服务,是国内移动互联网领域成长最快的产品服务之一。">
  9. </head>
  10. <body>
  11. <div>
  12. ......
  13. </div>
  14. </body>
  15. </html>

2.1.3分析首页html内容得到新闻所在li布局

  1. def _parseNews(self, url):
  2. resHtml = self.__getTouTiaoHtml(url)
  3. if not resHtml:
  4. print("解析内容出错")
  5. return
  6. # 转换为etree解析模式内容
  7. etree_html = etree.HTML(resHtml)
  8. # 通过前面对每条新闻dom结构分析,由xpath方式提取所有新闻所在的<li>布局
  9. li_elements = etree_html.xpath('//ul[@infinite-scroll-immediate-check][@infinite-scroll-immediate-check-count="containerCheckCount"]/li')
  10. # 解析得到的新闻列表
  11. parseNewsInfo = []
  12. # 新闻解析类
  13. parseNew = PaseNews()
  14. if li_elements and len(li_elements) > 0:
  15. for li in li_elements:
  16. newinf = parseNew.parse(li)
  17. if newinf:
  18. parseNewsInfo.append(newinf)
  19. print(" 标题:'%s'\n 图片:'%s'\n 作者:'%s'\n 类型:'%s'\n 时间:'%s'\n 布局:'%s'\n" % (newinf.title, newinf.imgurl, newinf.author, newinf.category,newinf.publish_time, newinf.news_type.value))
  20. else:
  21. return

函数_parseNews从获取到的整个html页面内容中,根据前面的分析所知我们的目标新闻内容都是在<ul>标签的<li>里面,根据这个规律,我们先把整个页面格式化为lxml格式:etree_html = etree.HTML(self.resHtml),然后通过xpath路径选择出我们所有的li元素:

  1. li_elements = etree_html.xpath('//ul[@infinite-scroll-immediate-check][@infinite-scroll-immediate-check-count="containerCheckCount"]/li')

咱好好说道说道这个xpath的用法,后续核心工作都是通过它来帮助我们完成的。

xpath() 的参数,前后用单引号包起来,//双斜杠开头,表示从整个文档任何位置,只要能匹配到就行。根据我们之前对首页元素的分析,只会有一个<ul>元素,所以我们etree_html.xpath('//ul)这么写,只会找到这一个,而不必关系它的父级、祖父级等到底有多少层,每层又是什么标签~

当然这里为了严谨点,还在ul后面加了个限制符:[@infinite-scroll-immediate-check] ,限制符放在中括号[]里面,@后面加标签的属性名,比如[@class="title"],表示当前元素必须要有class属性,并且属性值等于title,如果我们不关心属性的值,只需要有这个属性就行了,那么直接写[@属性名]

对属性的限定,除了通过等号=,还可以通过contains(表示属性值必须包含xxx)、starts-with(表示属性值必须以xxx开头),举个例子:

我要查找某个包含title属性,并且title的值包含group的a标签内容,可以这么写:xxx.xpath('//a[contains(@title, "group")]')

我要查找某个包含title属性,并且title的值以item-click开头的div标签内容,可以这么写:xxx.xpath('//div[starts-with(@title, "item-click")]')


记住xxx.xpath() 返回的要么是None,要么是list,即使只找到一个符合要求的,也是返回一个list(只有一个元素,可以通过==[0]== 下标得到这个元素)

2.2、编写解析具体新闻的代码

2.2.1、自定义新闻信息

我们从主入口的代码可以看到引入了两个自定义的类:

  1. # 自定义的新闻结构体
  2. from newsInfo import NewsInfo
  3. # 自定义解析html结构的实现类
  4. from parseNews import PaseNews

其中NewsInfo是存储我们解析出来的新闻内容结构,具体代码如下

  1. # -*- coding: utf-8 -*-
  2. from enum import Enum, unique
  3. @unique
  4. class NewsType(Enum):
  5. TextType = '纯文本类型'
  6. SingleImageType = '图文类型'
  7. MultipleImageType = '多图类型'
  8. VideoType = '视频类型'
  9. class NewsInfo:
  10. # 标题
  11. title = ''
  12. # 作者
  13. author = ''
  14. # 分类
  15. category = ''
  16. # 发表时间
  17. publish_time = ''
  18. # 图片url
  19. imgurl = []
  20. # 详情url
  21. detail_link = ''
  22. news_type = NewsType.TextType

2.2.2、解析新闻内容

而另一个PaseNews 类则是我们解析新闻html结构的核心类,具体代码如下:

2.2.2.1、新闻html内容分类判断

  1. def parse(self, li_etree):
  2. newsInfo = None
  3. # 获取当前新闻类型
  4. if li_etree.xpath('./div[@class="no-mode"]'):
  5. # 纯文本类型
  6. newsInfo = self.__parseTextNew(li_etree)
  7. elif li_etree.xpath('./div[contains(@class, "single-mode")][contains(@class, "bui-box")]'):
  8. # 单图片类型
  9. newsInfo = self.__parseImageNew(li_etree)
  10. elif li_etree.xpath('./div[@class="more-mode"][@ga_event="gallery_item_click"]'):
  11. # 多图片类型
  12. newsInfo = self.__parseImageListNew(li_etree)
  13. elif li_etree.xpath('./div[contains(@class, "video-mode")]'):
  14. # 视频类型
  15. newsInfo = self.__parseVideoNew(li_etree)
  16. return newsInfo

上面的parse函数,接收的参数是前面主入口拿到的整个html页面内容,经过分析得到的每一个li元素结构, 针对每一个li元素,通过前面的分析判断出它是哪种类型的新闻,然后单独调用相应的方法解析得到新闻内容

2.2.2.2、解析纯文本类型新闻

  1. 我们先看纯文本类型的html元素结构:
  1. <li class="">
  2. <div class="no-mode" ga_event="article_item_click">
  3. <div class="title-box" ga_event="article_title_click"><a class="link" target="_blank" href="/group/6605095646191944196/">国家主席习近平任免驻外大使</a></div>
  4. <div class="bui-box footer-bar">
  5. <div class="bui-left footer-bar-left"><a class="footer-bar-action tag tag-style-other" ga_event="article_tag_click"
  6. target="_blank" href="search/?keyword=%E6%97%B6%E6%94%BF">时政</a> <a class="footer-bar-action media-avatar"
  7. ga_event="article_avatar_click" target="_blank" href="/c/user/4377795668/"><img lazy="loaded" src="//p2.pstatp.com/large/3658/7378365093"></a>
  8. <a class="footer-bar-action source" ga_event="article_name_click" target="_blank" href="/c/user/4377795668/">&nbsp;新华网&nbsp;⋅</a>
  9. <a class="footer-bar-action source" ga_event="article_comment_click" target="_blank" href="/group/6605095646191944196//#comment_area">&nbsp;52评论&nbsp;⋅</a>
  10. <span class="footer-bar-action">&nbsp;38分钟前</span>
  11. <!---->
  12. <!---->
  13. <!---->
  14. </div>
  15. <div class="bui-right">
  16. <div dislikeurl="/api/dislike/" class="action-dislike" ga_event="dislike_click"><i style="font-size: 16px; color: rgb(221, 221, 221);"
  17. class="bui-icon icon-close_small"></i>
  18. 不感兴趣
  19. </div>
  20. </div>
  21. </div>
  22. </div>
  23. </li>
  1. python解析的代码如下:
  1. """
  2. 解析纯文本类型新闻
  3. """
  4. def __parseTextNew(self, li_etree):
  5. new_info = NewsInfo()
  6. # 获取标题
  7. new_info.title = li_etree.xpath('./div[@class="no-mode"]/div[1]/a/text()')[0]
  8. # 获取详情的相对地址
  9. new_info.detail_link = li_etree.xpath('./div[@class="no-mode"]/div[1]/a/@href')[0]
  10. # 获取新闻作者
  11. new_info.author = li_etree.xpath('./div[@class="no-mode"]/div[2]/div[1]/a[contains(@class, "source")][starts-with(@href, "/c/user/")]/text()')[0].replace("⋅", '').strip()
  12. # 获取新闻发布时间
  13. new_info.publish_time = li_etree.xpath('./div[@class="no-mode"]/div[2]/div[1]/span[@class="footer-bar-action"]/text()')[0].strip()
  14. # 获取新闻类型
  15. category = li_etree.xpath('./div[@class="no-mode"]/div[2]/div[1]/a[@ga_event="article_tag_click"]/text()')
  16. # 不一定有这个字段
  17. if category and len(category) > 0:
  18. new_info.category = category[0]
  19. # 新闻布局类型
  20. new_info.news_type = NewsType.TextType
  21. return new_info

简单说下,获取标题,

  1. new_info.title = li_etree.xpath('./div[@class="no-mode"]/div[1]/a/text()')[0]

传入来的已经是一个单独的li结构了,xpath里面的路径选择以./开头,表示从当前级别开始查找,查找class属性值为no-modediv,然后 紧跟着的/div[1]再继续找刚才定位到的这个div的下一级子元素中的div第一个,然后继续查找这个传入的li标签下的第二级div下面的a标签,最后获取这个a标签的字符串内容,注意,返回的是一个list,虽然这里最终只能定位到一个元素但仍然返回list形式,所以最后通过[0]下标引用得到这个标题字符串.

2.2.2.3、解析单图文类型新闻

参考上面2.2.2.1的分析思路,再不行就看本文源码,在本文最后那里下载

2.2.2.4、解析多图文类型新闻

参考上面2.2.2.1的分析思路,再不行就看本文源码,在本文最后那里下载

2.2.2.5、解析纯视频类型新闻

参考上面2.2.2.1的分析思路,再不行就看本文源码,在本文最后那里下载

最后,看下咱的成果如何 ↓


本文完整代码 →:下载地址

注意,上面下载的源码,为了测试方便,写死了静态html内容来解析演示的按照下图修改后可以正常解析线上的内容…


全文完结,后续实现用其它框架来爬虫新闻资源。敬请期待~


Python3从零开始爬取今日头条的新闻【一、开发环境搭建】

Python3从零开始爬取今日头条的新闻【二、首页热点新闻抓取】

Python3从零开始爬取今日头条的新闻【三、滚动到底自动加载】

Python3从零开始爬取今日头条的新闻【四、模拟点击切换tab标签获取内容】

Python3从零开始爬取今日头条的新闻【五、解析头条视频真实播放地址并自动下载】


参考资料:

[1]: XPath语法参考
[2]: 廖雪峰老师的Python3 在线学习手册

[3]: Python3官方文档

[4]: 菜鸟学堂-Python3在线学习

[5]: 其他所有分享过python学习填坑网友的经验

Python3从零开始爬取今日头条的新闻【二、首页热点新闻抓取】的更多相关文章

  1. 【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图【华为云技术分享】

    [摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...

  2. 【Python3网络爬虫开发实战】 分析Ajax爬取今日头条街拍美图

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:haoxuan10 本节中,我们以今日头条为例来尝试通过分析Ajax请求 ...

  3. 转:【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图

    [摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...

  4. PYTHON 爬虫笔记九:利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集(实战项目二)

    利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集 目标站点分析 今日头条这类的网站制作,从数据形式,CSS样式都是通过数据接口的样式来决定的,所以它的抓取方法和其他网页的抓取方 ...

  5. Python3从零开始爬取今日头条的新闻【一、开发环境搭建】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

  6. Python3从零开始爬取今日头条的新闻【四、模拟点击切换tab标签获取内容】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

  7. Python3从零开始爬取今日头条的新闻【三、滚动到底自动加载】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

  8. 使用scrapy爬虫,爬取今日头条搜索吉林疫苗新闻(scrapy+selenium+PhantomJS)

    这一阵子吉林疫苗案,备受大家关注,索性使用爬虫来爬取今日头条搜索吉林疫苗的新闻 依然使用三件套(scrapy+selenium+PhantomJS)来爬取新闻 以下是搜索页面,得到吉林疫苗的搜索信息, ...

  9. 使用scrapy爬虫,爬取今日头条首页推荐新闻(scrapy+selenium+PhantomJS)

    爬取今日头条https://www.toutiao.com/首页推荐的新闻,打开网址得到如下界面 查看源代码你会发现 全是js代码,说明今日头条的内容是通过js动态生成的. 用火狐浏览器F12查看得知 ...

随机推荐

  1. python 内置数据类型之数字

    目录: 1.2. 数字 1.2.1. 数字类型 1.2.2. 浮点数 1.2.3. 进制记数 1.2.4. 设置小数精度 1.2.5. 分数 1.2.6. 除法 1.2 数字   1.2.1 数字类型 ...

  2. jenkins原理

      原理:Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 直白的说:这个jenkins是CI ...

  3. Tomcat使用

    打开Tomcat官网 在浏览器地址栏输入: tomcat.apache.org,按回车 下载Tomcat 把目光移动至网页左边红匡处,点击Tomcat8 网页下移 点击箭头所指的链接 运行Tomcat ...

  4. B: Ocean的游戏(前缀和)

    B: Ocean的游戏 Time Limit: 1 s      Memory Limit: 128 MB Submit My Status Problem Description 给定一个字符串s, ...

  5. 去掉A标签的点击选中边框

    非IE a:focus { outline:none; }

  6. TagCanvas 插件

    TagCanvas是一个基于HTML5 Canvas技术开发的标签云动画.还提供一个以jQuery插件形式实现的版本. 它支持文本和图片两种格式,能够以Sphere, hcylinder 或 vcyl ...

  7. [转] HTML5+规范:device(管理设备信息)

    http://blog.csdn.net/qq_27626333/article/details/51815310 Device模块管理设备信息,用于获取手机设备的相关信息,如IMEI.IMSI.型号 ...

  8. MySQl 查询性能优化相关

    0. 1.参考 提升网站访问速度的 SQL 查询优化技巧 缓存一切数据,读取内存而不是硬盘IO 如果你的服务器默认情况下没有使用MySQL查询缓存,那么你应该开启缓存.开启缓存意味着MySQL 会把所 ...

  9. [转]10 Awesome Indicator Applets for Ubuntu’s Unity Desktop

    http://blogger.gtwang.org/2013/10/awesome-indicator-applets-for-ubuntus-unity-desktop.html http://ww ...

  10. net core体系-web应用程序-4net core2.0大白话带你入门-2asp.net core新建项目

    新建asp.net core项目   开发环境:Windows Server R2 2008 开发工具:Microsoft Visual Studio 2017 新建asp.net core项目 创建 ...