今天我们下载头条的图片内容。
进入头条首页,我们根据关键词搜索。

发现有搜索出很多的条目,而且条目是根据鼠标往下滑动的时候就会动态加载出来,是动态更新的,之前我们曾使用过Selenium进行模拟鼠标滑动,一次性获得了很多的条目,最后再把所有页面的对应图片组的入口找出来,而今天我们试图用分析http request请求的方式来搞一次,每一次动态加载都是一次请求,所以我们来试图分析分析请求,看看能不能做出来。

每一个条目点击进去能看到相应的文章里面有很多图片,说明是一个图片组。

好了,看了大概的内容展示后,言归正传,我们进入正题。
首先我们得来分析下每一次动态加载得http请求,看看能不能找到什么item规律,于是打开开发者窗口,请按“F12”。然后不断下滑下滑进行动态加载,我们再network窗口进行观察。
如下:



我们连续请求四次,发现四次得请求在数据请求上很有规律。

每一次都是offset不一样,offset就是分页得偏移,count是每一次分页得总数,整个是保持不变,
每一次得timestamp和_signature也是不一样得,但是经过测试发现,这俩可以不用加上,也就是对于爬取数据来说没啥用处,可以忽略掉。

每一次请求后,得到的数据是:


每一个组图都有一个groupId,我们拿到这个ID后,打开json中的article_url,发现会跳转到另外一个地址,比如地址会从

输入:https:// toutiao.com/group/6887210541710836232/
跳转到:https://www.toutiao.com/a6887210541710836232/

这样我们通过groupid来拼装出组图的文章地址,使用Selenium来打开页面,找到所有的img,进行下载!

组图页面的每个图片的class都是 “syl-page-img”。嗯,这就不难了,不错!
好了整个过程就是这样的。现在给出完整代码:

import requests
from urllib.parse import urlencode
import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import  Options
import os
from concurrent.futures import ThreadPoolExecutorchromeExeLoc = 'D:/software/chrome/chromedriver_win32/chromedriver.exe'
rootrurl = 'https://www.toutiao.com/api/search/content/?'
ERROR_SELF_DEF = "ERROR"
save_dir = 'D:/estimages/'
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",'Accept-Language': 'en-US,en;q=0.8','Cache-Control': 'max-age=0','Connection': 'keep-alive'}  # 伪装成浏览器# 根据某个url和一堆参数去获得某个json数据
def request_url_data(url):# 获得json数据try:resp = requests.get(url,headers=headers)if resp.status_code == 200:return resp.textexcept requests.RequestException as e:print('fail to get json data.')return ERROR_SELF_DEFdef saveOneImg(dir, img_url):new_headers = {"Referer": img_url,'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",'Accept-Language': 'en-US,en;q=0.8','Cache-Control': 'max-age=0','Connection': 'keep-alive'}  ###设置请求的头部,伪装成浏览器,实时换成新的 header 是为了防止403 http code问题,防止反盗链,try:img = requests.get(img_url, headers=new_headers)  # 请求图片的实际URLif (str(img).find('200') > 1):with open('{}/{}.jpg'.format(dir, img_url.split('/')[-1].split('?')[0]), 'wb') as jpg:  # 请求图片并写进去到本地文件jpg.write(img.content)print(img_url)jpg.close()return Trueelse:return Falseexcept Exception as e:print('exception occurs: ' + img_url)print(e)return Falsedef downloadAllImgs(imgs, dir):if not os.path.exists(dir):os.makedirs(dir)for img in imgs:saveOneImg(dir, img.get_attribute('src'))pass# 再一个字符串s中找到所有的字串substr
def find_all(sub, s):index_list = []index = s.find(sub)while index != -1:index_list.append(index)index = s.find(sub, index + 1)if len(index_list) > 0:return index_listelse:return -1# 得到所有的文章的groupId
def parseArticles(json):json = json.replace(' ','')li = find_all('"group_id"', json)urls = []for item in li:beg = json.find(':', item)+2# beg = json.find('http', item)end = json.find(',', item)-1urls.append(json[beg:end])return urlsdef searchKeyWord(offset, keyword, browser):ts = str(time.time()).replace('.', '')[0:13]params = {'aid': 24,'app_name': 'web_search','offset': offset,'format': 'json','keyword': keyword,'autoload': 'true','count': 20,'en_qc': 1,'cur_tab': 1,'from': 'search_tab','pd': 'synthesis','timestamp': ts,}# 拼装urlurl = rootrurl + urlencode(params)# 通过url去异步请求json数据json = request_url_data(url)# 解析json然后得到所有的文章的groupIdgroupIds = parseArticles(json)for groupId in groupIds:article = '{}{}/'.format('https://www.toutiao.com/a', groupId)print(article)browser.get(article)  # get theimgs = browser.find_elements_by_class_name('syl-page-img')downloadAllImgs(imgs, '{}{}/{}'.format(save_dir, keyword, groupId))def tagSpider(keyword):# 无头浏览器 这样浏览器就不会弹出那个chrome的web浏览器界面options = Options()options.add_argument('--headless')browser = webdriver.Chrome(chromeExeLoc)browser.maximize_window()browser.implicitly_wait(10)# 别贪心,只抓取几次即可。for offset in range(20, 100, 20):print('start.............., offset=%s' % offset)searchKeyWord(offset, keyword, browser)print('end.................')browser.close()browser.quit()if __name__ == '__main__':# 获得所有标签taglist = ['动漫', '街拍美女', '林珍娜', '火影忍者']## 给每个标签配备一个线程with ThreadPoolExecutor(max_workers=15) as t:  # 创建一个最大容纳数量为20的线程池for tag in taglist:t.submit(tagSpider, tag)# 单个连接测试下下# tagSpider('三吉彩花')# 等待所有线程都完成。while 1:print('-------------------')time.sleep(1)

效果图如下:


Python《通过解析http请求搞定动态加载,爬取toutiao图片》相关推荐

  1. Github配置(git+vscode+python+jupyter)

    ①下载git 打开 git bash 工具的用户名和密码存储 $ git config --global user.name "Your Name" $ git config -- ...

  2. 【实验楼】python简明教程

    ①终端输入python进入 欣赏完自己的杰作后,按 Ctrl + D 输入一个 EOF 字符来退出解释器,你也可以键入 exit() 来退出解释器. ②vim键盘快捷功能分布 ③这里需要注意如果程序中 ...

  3. 【Kaggle Learn】Python 5-8

    五. Booleans and Conditionals Using booleans for branching logic x = True print(x) print(type(x))''' ...

  4. 【Kaggle Learn】Python 1-4

    [Kaggle Learn]Python https://www.kaggle.com/learn/python 一. Hello, Python A quick introduction to Py ...

  5. 使用python愉快地做高数线代题目~

    今天接触到了python,发现真是极易上手啊!对比c语言是什么鬼东西= = 诶,等下,看完教学文章发现TA在下面写了这句话 如果做了前面的内容你可能已被吸引了,觉得c语言真的是废材! 不...不是的. ...

  6. python 位运算与等号_Python 运算符

    和大多数语言一样,Python也有很多运算符,并且运算符跟其他语言的运算符大同小异接下来一一介绍: 算术运算符: 运算符描述实例 +加 - 两个对象相加a+b的输出结果是30 -减 - 得到复数或者一 ...

  7. python减小内存占用_如何将Python内存占用缩小20倍?

    当程序执行过程中RAM中有大量对象处于活动状态时,可能会出现内存问题,特别是在对可用内存总量有限制的情况下. 下面概述了一些减小对象大小的方法,这些方法可以显著减少纯Python程序所需的RAM数量. ...

  8. python中排序英文单词怎么写_Python实现对文件进行单词划分并去重排序操作示例...

    本文实例讲述了Python实现对文件进行单词划分并去重排序操作.,具体如下: 文件名:test1.txt 文件内容: But soft what light through yonder window ...

  9. python程序如何执行死刑图片_如何判断对象已死

    已死的对象就是不可能被任何途径使用的对象,有以下几种方法判断一个对象是否已经死了: 引用计数 给对象添加一个引用计数器,每当有一个地方引用他,计算器就加 1:当引用失效时,计数器减 1:任何时刻计数器 ...

  10. Python gRPC 安装

    1. 安装依赖库 sudo pip3 install grpcio sudo pip3 install protobuf sudo pip3 install grpcio_tools 2. 生成对应文 ...

最新文章

  1. Machine Learning | (4) Scikit-learn的分类器算法-逻辑回归
  2. linux插光驱自动重启,Linux两种光驱自动挂载的方法
  3. parzen窗估计如何进行结果分析_实现一下模式识别(一)Parzen窗估计
  4. windows 下安装 rabbitmq报init terminating in do_boot错误
  5. 管道过滤器(Pipe-And-Filter)模式
  6. python的进程和线程_Python进程与线程知识
  7. 从测试流程角度,阿里P8大佬对产品质量的一些总结思考...
  8. [转 js] 分析JsUnit
  9. 32 位的有符号整数_「js基础」JavaScript逻辑和位运算符归纳
  10. P3372 【模板】线段树 1 区间查询与区间修改
  11. 国美易卡设置cookie域,国美易卡匹配domain
  12. Salesforce基础知识学习Day05
  13. 张伯旭:北京亦庄着力打造中国云产业园
  14. Openstack Cinder Ceph(RBD)备份恢复过程(backup/restore)
  15. 关于ios9中得AddressBook和AddressBookUI框架过时问题
  16. Linux基础第一课——基础知识了解
  17. SDUST 实验+ 作业
  18. 公司企业微信公众号怎么创建小程序?
  19. Java 常用工具类 - 校验身份证 IdCardUtils
  20. 下拉列表之前后端交互

热门文章

  1. Guava学习笔记:Ordering犀利的比较器
  2. uniGUI试用笔记(四)
  3. Mac OS X下安装Java 7及配置Eclipse JDK
  4. Cannot delete .... . Name node is in safe mode
  5. magento 删除所有用户订单 delete order customer
  6. 管理功能(下):EqualLogic PS5000 强大丰富
  7. 面试:高并发下的流量控制
  8. JavaScript 设计模式核⼼原理与应⽤实践 之 结构型设计模式
  9. Linux 下 Oracle 内核参数优化
  10. 隐马尔可夫(HMM)/感知机/条件随机场(CRF)----词性标注