1 目标网站分析

首先我们打开今日头条网站,搜索 街拍,点击图集,这里每就是我们要爬取的目录,我们称为索引页。1

点开一个标题,进去,称为详情页。2这里面的图是我们所要爬取的。比如这里可以点击图片,共7张图。2

这里我们可以想到,可以先把详情页的每个标题URL爬取下来,再请求详情页得到每个图集。

分析详情页代码,打开谷歌浏览器开发工具,选择Network,刷新网页。发现第一个请求中返回的不含图片的任何信息。

想到头条应该是Ajax请求,选择XHR,继续刷新,点击图集。发现我们点击图集发出的请求返回的代码中data中含有我们想要的图片信息,是Json格式。可以看到title信息,刚好符合。
3

Headers,属于get请求,可以看到请求参数。
4

也可以看到我们请求索引页的网址。

然后滑动网页,发现左边又多了个请求,offset=20,由此得知索引页可通过改变offset来换页。6

继续看详情页,我们想找到每个图集的内容。同样打开network工具,刷新网页。选择XHR,发现每个请求中都不包含图集信息。选择ALL查看,我们可以看到对应网址的请求返回了一段代码。我们右击图片,新窗口查看,得到图片的地址后面的数字。到前面的代码中搜索,发现图片信息恰好在gallery: JSON.parse(” “)中,是Json格式。其中’sub_image’的值包含的就是我们想要获取的图集的信息。7

理一下基本思路:

  1. 爬取索引页的信息。通过分析ajax请求,得到每个详情页的网址。(比如这里就返回了18个详情页)
  2. 爬取详情页的信息,分析网页代码,用正则表达式得到每个图集的信息。
  3. 将爬取的信息存到MongoDB,并下载图片。
  4. 通过改变offset爬取多页信息,利用多线程加快速度。

2 流程框架

  • 抓取索引页内容

    利用requests请求目标站点,得到索引网页HTML代码,返回结果。

  • 抓取详情页内容

    解析返回结果,得到详情页的链接,并进一步抓取详情页的信息。

  • 下载图片与保存数据库

    将下载的图片保存到本地,并把页面信息及图片URL保存至MongDB.

  • 开启循环和多线程

    对多页内容遍历,开启多线程提高抓取速度。

3 爬虫实战

使用pycharm。

3.1 抓取索引页内容

def get_page_index(offset, keyword):"""抓取索引页的内容"""data = {  # 请求参数,offset和keyword我们设置成变量,方便改变。'offset': offset,'format': 'json','keyword': keyword,'autoload': 'true','count': 20,'cur_tab': 3,'from': 'gallery'}# urlencode()可以把字典对象转化为url的请求参数url = 'https://www.toutiao.com/search_content/?' + urlencode(data)try:  # 防止程序中断response = requests.get(url)  if response.status_code == 200:  # 如果访问成功则返回文本内容return response.textreturn Noneexcept RequestException:print('请求索引页出错')return None

3.2 解析索引数据

def parse_page_index(html):""" 解析索引数据"""# json.loads()对JSON数据进行解码,转换成一个字典data = json.loads(html)# 当data这个字典存在且'data'键名存在与data字典中。data.keys()返回data这个字典所有的键名if data and 'data' in data.keys():# get() 函数返回字典中指定键的值,在这里遍历data字典中键名为'data'的# 值,每个元素分别为一个图集。for item in data.get('data'):# 对于'data'的值中的每个元素,建立一个生成器,得到每个网址yield item.get('article_url')  # 'article_url'中信息是每个图集的网址

3.3 获取详情页信息

def get_page_detail(url):""" 拿到详情页图的信息"""try:# 此处不加headers会导致访问详情页失败headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64;x64)AppleWebKit/537.36(KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}response = requests.get(url, headers=headers)if response.status_code == 200:return response.textreturn Noneexcept RequestException:print('请求详情页出错', url)return None

3.4 解析详情页

def parse_page_detail(html, url):""" 解析详情页"""# 声明解析后的网页对象soup = BeautifulSoup(html, 'lxml')# 通过传入css选择器,选择第一个<title>标签,获取文本内容,就是图集的标题。title = soup.select('title')[0].get_text()# 声明一个正则表达式对象,来匹配我们想要的Json语句。注意re.S使 . 能匹配任意字符。images_pattern = re.compile('gallery: JSON.parse\("(.*?)"\),', re.S)result = re.search(images_pattern, html)# 注意:这里的Json语句包含转义字符 \ ,不去掉会报错result = result.group(1).replace('\\', '')# result = re.sub(r'\\', '', result.group(1))if result:  # 结果存在则进行data = json.loads(result)  # 把Json转换为字典if data and 'sub_images' in data.keys():# 'sub_images'这个键的值是一个列表,里面每个元素是字典,包含每个图集的地址。sub_images = data.get('sub_images')   # 得到图集的地址images = [item.get('url') for item in sub_images]  # 构造一个图集列表,包含每个图片的地址。for image in images:download_image(image)  # 下载每张图片return {  # 返回一个字典,格式化数据,准备存入MongoDB'title': title,'url': url,'images': images,}

3.5 定义下载图片函数

def download_image(url):  # 传入的是每张图片的地址""" 下载图片"""print('正在下载', url)  # 调试信息try:headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36''(KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}response = requests.get(url, headers=headers)if response.status_code == 200:save_image(response.content)  # 保存图片,content返回二进制内容(当保存图片视频时)return Noneexcept RequestException:print('请求图片出错', url)return None

3.6 定义保存图片函数

def save_image(content):"""存图片"""# 定义文件路径,文件名把图片信息md5加密,保证每个文件名不同。file_path = '{0}/{1}.{2}'.format(os.getcwd() +'\images', md5(content).hexdigest(), 'jpg')if not os.path.exists(file_path):  # 如果文件不存在with open(file_path, 'wb') as f:f.write(content)
'''
w     以写方式打开,不存在则创建
a     以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+     以读写模式打开
w+     以读写模式打开 (参见 w )
a+     以读写模式打开 (参见 a )
rb     以二进制读模式打开
wb     以二进制写模式打开 (参见 w )
ab     以二进制追加模式打开 (参见 a )
rb+    以二进制读写模式打开 (参见 r+ )
wb+    以二进制读写模式打开 (参见 w+ )
ab+    以二进制读写模式打开 (参见 a+ )'''

3.7 存储到数据库

client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
# 其中MONGO_DB,MONGO_URL为配置文件中的参数
def save_to_mongo(result):"""存储文件到数据库"""if db[MONGO_DB].insert(result):print('存储成功', result)return Truereturn False

3.8 主函数

def main(offset):""" 主函数"""html = get_page_index(offset, KEYWORD)  # 获取索引页网页内容for url in parse_page_index(html):  # parse_page_index()返回一个生成器,生成每个图集的地址html = get_page_detail(url)  # 得到每个图集详情页的内容if html:  # 如果内容返回成功result = parse_page_detail(html, url) # 解析详情页,返回一个字典结果save_to_mongo(result)  # 存入数据库

3.9 运行

if __name__ == '__main__':groups = [x * 20 for x in range(GROUP_START, GROUP_END + 1)]  # 生成一个offset列表pool = Pool()  # 声明一个进程池pool.map(main, groups)pool.close()pool.join()

3.10 头文件

import json
import os
import re
from hashlib import md5
from multiprocessing import Poolfrom urllib.parse import urlencode
import pymongo
import requests
from bs4 import BeautifulSoup
from requests.exceptions import RequestExceptionfrom ToutiaoJiepai.config import *

3.11 创建配置文件config.py

# config.py
MONGO_URL = 'localhost'
MONGO_DB = 'toutiao'
MONGO_TABLE = 'toutiao'GROUP_START = 1
GROUP_END = 1
KEYWORD = '街拍'

多用if语句的异常语句来保证程序的顺利进行。

Python爬虫实战02:分析Ajax请求并抓取今日头条街拍相关推荐

  1. python爬虫今日头条街拍美图开发背景_分析Ajax请求并抓取今日头条街拍美图:爬取详情页的url与实际页面上显示不符...

    from urllib.parse import urlencode import re from requests.exceptions import RequestException from b ...

  2. 分析Ajax请求并抓取今日头条街拍美图

    1.抓取索引页内容 利用requests请求目标站点,得到索引网页HTML代码,返回结果 2.抓取详情页内容 解析返回结果,得到详情的链接,并进一步抓取详情页的信息 3.下载图片与保存数据库 将图片下 ...

  3. 2.分析Ajax请求并抓取今日头条街拍美图

    import requests from urllib.parse import urlencode # 引入异常类 from requests.exceptions import RequestEx ...

  4. 分析Ajax抓取今日头条街拍美图

    声明:此篇文章主要是观看静觅教学视频后做的笔记,原教程地址https://cuiqingcai.com/ 实现流程介绍 1.抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码, ...

  5. python爬今日头条组图_python 爬虫抓取今日头条街拍图片

    1. 打开google浏览器,输入www.toutiao.com, 搜索街拍.html 2.打开开发者选项,network监看加载的xhr, 数据是ajax异步加载的,能够看到preview里面的da ...

  6. php抓取今日头条,分析Ajax来抓取今日头条街拍美图

    一.介绍 还是根据崔大大的视频来码的文章,不得不说,抓取文件并下载下来比抓取网页内容信息复杂多了 二.流程 目标站点分析 用浏览器打开今日头条输入'街拍',打开审查元素,点击'图集' 1.首先我们要找 ...

  7. ajax动态抓取今日头条街拍美图

    1.分析网站源码. 网站是局部动态变化,offset变化加载内容,变化范围为0,20,40··· 首先要获取索引页代码数据,定义索引页,由于是ajax请求,offset根据索引变化0.20.40··· ...

  8. [Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图

    [Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图 学习笔记--爬取今日头条街拍美图 准备工作 抓取分析 实战演练 学习笔记–爬取今日头条街拍美图 尝试通过分析Ajax请求来抓取 ...

  9. Python爬虫 | 批量爬取今日头条街拍美图

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今日鸡汤浮云一别后,流水十年间. 专栏作者:霖he ...

最新文章

  1. AI一周热闻:GitHub免费开放无限私有库;苹果市值蒸发超450亿美元;小米入股TCL...
  2. C++ 落选,2021 年最想学习的五大编程语言
  3. python timer使用-python下timer定时器常用的两种实现方法
  4. 控制台ui_设计下一代控制台UI
  5. Oracle-一个中文汉字占几个字节?
  6. 计算机电缆对绞节距,DJYPVP阻燃计算机电缆32/0.2芯数直径
  7. java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap
  8. 前端中怎么把网页多个文件夹的内容整合成一个_web前端学习笔记
  9. A Game with Traps—— 二分
  10. Java多线程 - 解析线程的5种/6种状态
  11. 手撸JDK之ReentrantLock锁那点事
  12. 微信小程序合并单元格
  13. 把多列的迭代次数问题化简为单列问题
  14. Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码
  15. Hello,你好JAVA
  16. matlab premnmx归一化函数的使用
  17. Chirp信号简单介绍
  18. 股市投资必修课二十二---资本回报率
  19. 干货|数据分析之落地sop流程(一)
  20. 一个开发周期为6个月的中小型软件开发项目成本预算大致表

热门文章

  1. 文件创建时间、访问时间、修改时间
  2. IOCP扩展方法AcceptEx, DisconnectEx, GetAcceptExSockaddr用法示例
  3. 一个项目需要提交哪了些文档?
  4. 「Luogu P2201」数列编辑器 解题报告
  5. choices相当于实现一个简化版的外键
  6. IntelliJ IDEA 2018.2.2及以下版本破解方法
  7. 多路I/O转接之select模型
  8. 东软实训2-在jsp中使用javaBean
  9. C#中,当从数据库中查询到数据,以DataTable类型返回后,如果需要对DataTable中的数据进行筛选,可以选择下面的方式...
  10. Thanos 开源的大规模Prometheus集群解决方案