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

  通常我们从网页上爬取内容时,都是HTML代码,内容都已经写好了,直接从页面获取想要的信息即可,但是有的网页是通过ajax获取的数据,将ajax获取的数据通过json格式接受,然后展示在页面上的,也就是说,当我们打开一个页面时,首先请求的是他的html,然后HTML里面通过ajax获取后端数据,将数据以json格式展示在页面上。而近日头条就是这样。下面我们来看看。

  我们打开链接:https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D,我们发现下面图片的链接和我们粘贴复制过来的地址不一样,说明最终请求的数据通过了ajax请求,数据格式发生了改变。我们查看网页源码,发现页面中没有关于我们在头条中看到的信息。

我们使用开发者选项F12,查看网页元素,发现请求头header中url与我们上面的连接不一样,增加了很多信息

我们查看请求的参数,发现有很多参数,这就是通过ajax真正访问的数据连接,我们需要的就是将https://www.toutiao.com/search_content/?   +  加上下面的各种参数,就能查看到真正的数据源,

下面是请求网页源数据的代码:

#请求网页具体信息的函数
def get_page_index(offset,keyword):
    data={
        ‘offset‘: offset,
        ‘format‘: ‘json‘,
        ‘keyword‘: keyword,
        ‘autoload‘: ‘true‘,
        ‘count‘: ‘20‘,
        ‘cur_tab‘:3,
        ‘from‘: ‘search_tab‘
    }
    url=‘https://www.toutiao.com/search_content/?‘+urlencode(data)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

接下来应该解析网页中的数据:我们通过上面的请求方式获得的就是通过ajax请求返回的json数据,这些数据中我们需要每一条头条的链接,下面是解析函数:

def parse_page_index(html):
    data = json.loads(html)#将获取的ajax请求转换为json类型的数据
    if data and ‘data‘ in data.keys():
        for item in data.get(‘data‘):
            yield item.get(‘article_url‘)#从json数据中获取名为artile_url的数据

接下来我们需要根据上面获得url请求每一条头条的内容:

def get_page_datail(url):
    headers = {
        ‘User-Agent‘: ‘Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)APPleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36‘
    }
    try:
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print(‘出现错误‘)
        return None

注意:这里我们添加了请求头,添加请求头的原因是有的网页防止python爬取数据,我们可以通过伪代理或者添加header的方式来避免。

我们打开头条中的一条新闻,查看网页源代码,发现同样的我们看不到这条消息的数据,这些数据都包含在ajax请求返回的json数据中,我们需要从这些数据中提取

我们需要从网页中解析,下面是代码:

def pase_page_detail(html,url):
    soup=BeautifulSoup(html,‘lxml‘)#使用beautifulsoup解析库来解析网页
    title = soup.select(‘title‘)[0].get_text()#直接可以通过标签名来获取头条的名称
    print(title)
    images_pattern  = re.compile(‘BASE_DATA.galleryInfo.*?gallery: JSON.parse\("(.*?)"\),‘,re.S)#这里我们使用正则表达式获取我们想要图片的信息
    result = re.search(images_pattern,html)
    if not result is None:#有的网页中不含有符合正则表达式的内容,我们直接将之过滤
        data=json.loads(result.group(1).replace(‘\\‘,‘‘))#将\\转义替换为空字符,同时将图片的信息转为json格式
        if data and ‘sub_images‘in data.keys():#判断数据不为空并且里面含有图片的信息
            sub_images=data.get(‘sub_images‘)#从json数据中获取名为sub_images的内容
            images=[item.get(‘url‘) for item in sub_images]#有的新闻中含有多张图片,我们将图片的链接存在数组中
            for image in images:
                get_save_image(image)#请求图片的链接
            return{
                ‘title‘:title,
                ‘url‘:url,
                ‘image‘:images
            }#将我们得到的数据以数组格式返回,需要标题,url,还有图片链接

接下来我们需要将这些数据存放到MongoDB数据库,首先定义几个静态变量,新建一个config.py的python文件

MONGO_URL=‘localhost‘#数据库的ip就是localhost
MONGO_DB=‘toutiao‘#存放的数据库名称
MONGO_TABLE=‘toutiao‘#存放的表名称

在写代码的python文件中定义数据库:

client = pymongo.MongoClient(MONGO_URL,connect=False)
db = client[MONGO_DB]

下面是存放到MongoDB的函数:

def save_to_mongo(result):
    if db[MONGO_TABLE].insert(result):
        print(‘存储到数据库成功‘,result)
        return True
    return False

我们还有将图片保存在本地的函数,这里我直接上全部代码:

import json
import os
import re
from hashlib import md5
from multiprocessing import Pool

from urllib.parse import urlencode

import pymongo

from config import *
client = pymongo.MongoClient(MONGO_URL,connect=False)
db = client[MONGO_DB]

from bs4 import BeautifulSoup
from requests.exceptions import RequestException
import requests

#请求网页具体信息的函数
def get_page_index(offset,keyword):
    data={
        ‘offset‘: offset,
        ‘format‘: ‘json‘,
        ‘keyword‘: keyword,
        ‘autoload‘: ‘true‘,
        ‘count‘: ‘20‘,
        ‘cur_tab‘:3,
        ‘from‘: ‘search_tab‘
    }
    url=‘https://www.toutiao.com/search_content/?‘+urlencode(data)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

def parse_page_index(html):
    data = json.loads(html)#将获取的ajax请求转换为json类型的数据
    if data and ‘data‘ in data.keys():
        for item in data.get(‘data‘):
            yield item.get(‘article_url‘)#从json数据中获取名为artile_url的数据

def get_page_datail(url):
    headers = {
        ‘User-Agent‘: ‘Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)APPleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36‘
    }
    try:
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print(‘出现错误‘)
        return None

def pase_page_detail(html,url):
    soup=BeautifulSoup(html,‘lxml‘)#使用beautifulsoup解析库来解析网页
    title = soup.select(‘title‘)[0].get_text()#直接可以通过标签名来获取头条的名称
    print(title)
    images_pattern  = re.compile(‘BASE_DATA.galleryInfo.*?gallery: JSON.parse\("(.*?)"\),‘,re.S)#这里我们使用正则表达式获取我们想要图片的信息
    result = re.search(images_pattern,html)
    if not result is None:#有的网页中不含有符合正则表达式的内容,我们直接将之过滤
        data=json.loads(result.group(1).replace(‘\\‘,‘‘))#将\\转义替换为空字符,同时将图片的信息转为json格式
        if data and ‘sub_images‘in data.keys():#判断数据不为空并且里面含有图片的信息
            sub_images=data.get(‘sub_images‘)#从json数据中获取名为sub_images的内容
            images=[item.get(‘url‘) for item in sub_images]#有的新闻中含有多张图片,我们将图片的链接存在数组中
            for image in images:
                get_save_image(image)#请求图片的链接
            return{
                ‘title‘:title,
                ‘url‘:url,
                ‘image‘:images
            }#将我们得到的数据以数组格式返回,需要标题,url,还有图片链接

def save_to_mongo(result):
    if db[MONGO_TABLE].insert(result):
        print(‘存储到数据库成功‘,result)
        return True
    return False

def get_save_image(url):
    headers = {
        ‘User-Agent‘: ‘Mozilla/5.0(Macintosh;Intel Mac OS X 10_11_4)APPleWebKit/537.36(KHTML,like Gecko)Chrome/52.0.2743.116 Safari/537.36‘
    }
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            save_image(response.content)
        return None
    except RequestException:
        print(‘请求图片界面错误‘)
        return None
def save_image(content):
    file_path=‘{0}/{1}.{2}‘.format(os.getcwd(),md5(content).hexdigest(),‘jpg‘)
    if not os._exists(file_path):
        with open(file_path,‘wb‘)as f:
            f.write(content)
            f.close()

def main(offset):
    html=get_page_index(offset,‘街拍‘)
    for url in parse_page_index(html):
        if url:
            html1=get_page_datail(url)
            if html:
                result=pase_page_detail(html1,url)
                if not result is None:
                    save_to_mongo(result)

if __name__  == ‘__main__‘:
    groups = [x*2 for x in range(GROUP_START,GROUP_END+1)]
    pool = Pool()
    pool.map(main,groups)

下面就是在MongoDB中的信息:

原文地址:https://www.cnblogs.com/zll20153246/p/9671198.html

时间: 2024-10-03 04:55:46

分析Ajax请求并抓取今日头条街拍美图的相关文章

芝麻HTTP:分析Ajax爬取今日头条街拍美图

本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节开始之前,请确保已经安装好requests库. 2.实战演练 首先,实现方法get_page()来加载单个Ajax请求的结果.其中唯一变化的参数就是offset,所以我们将它当作参数传递,实现如下: import requests from urllib.parse import urlencode def

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

前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:haoxuan10 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 准备工作在本节开始之前,请确保已经安装好requests库.如果没有安装,可以参考第1章.另外如果你对python的库不是很熟的话,建议先去小编的Python交流.裙 :一久武其而而流

Ajax爬取今日头条街拍美图

1.打开今日头条:https://www.toutiao.com 2.搜索街拍 3.检查元素,查看请求发现在URL中每次只有offset发生改变,是一个get请求 1 import requests 2 from urllib.parse import urlencode 3 import os 4 from hashlib import md5 5 from multiprocessing.pool import Pool 6 7 def get_page(offset): 8 params

分析Ajax爬取今日头条街拍美图

1 import os 2 import requests 3 from urllib.parse import urlencode 4 from hashlib import md5 5 from multiprocessing.pool import Pool 6 7 GROUP_START = 1 8 GROUP_END = 5 9 10 def get_page(offset): 11 params = { 12 'offset': offset, 13 'format': 'json'

ajax分析-今日头条街拍美图抓取

我们知道,有时候直接利用requests请求得到的原始数据是无效的,因为很多时候,这样获取的一个网页的源代码很可能就几行,明显不是我们想要的东西,这个时候,我们就可以分析,这样的网页中是不是加入了ajax请求,即原始页面加载完成后,会再向服务器请求某个接口去获取数据,然后才被呈现到网上的. ajax并不是一门语言,而是一门技术,它可以在页面不被刷新的情况下,利用javascript进行数据交换,渲染网页进而呈现,我们平时用手机刷微博,往下拉就会出现加载的小圆圈,那个就是加入了ajax请求. 所以

多线程高容错爬头条街拍美图

分析头条的ajax,通过正则表达式,python3多线程高容错爬取头条的街拍美图,保存到mongodb,并下载图片 头条的内容网页较之前已经改版,图床页不仅有ajax的还有html的内容网页 所以使用了两种正则,根据条件调用 #!/usr/bin/env python # -*- coding:utf-8 -*- """ @author:Aiker @file:toutiao.py @time:下午9:35 """ import json imp

ajax爬取今日头条街拍图片——data出现none的解决

之前爬取总是出现如图的结果:手动打开url显示的是想要的结果,但是爬取的时候data为空 尝试了多种方法,偶然得到了想要的结果: 这是多次实验中成功与不成功结果中构造的url 发现 1)得到想要结果,所构造的url中keyword=******与下一参数间没有&链接 2)同样的keyword=%E8%A1%97%E6%8B%8D,参用不同的方式:‘https://www.toutiao.com/api/search/content/?keyword=%E8%A1%97%E6%8B%8D’+url

使用php蓝天采集器抓取今日头条ajax的文章内容

今日头条的数据都是ajax加载显示的,按照正常的url是抓取不到数据的,需要分析出加载出址,我们以 https://www.toutiao.com/search/?keyword=%E6%96%B0%E9%97%BB 为例来采集列表的文章 用谷歌浏览器打开链接,右键点击"审查"在控制台切换至network并点击XHR,这样就可以过滤图片.文件等等不必要的请求只看页面内容的请求 由于页面是ajax加载的,所以将页面拉至最底部,会自动加载出更多文章,这时候控制台抓取到的链接就是我们真正需要

python爬虫 selenium 抓取 今日头条(ajax异步加载)

from selenium import webdriver from lxml import etree from pyquery import PyQuery as pq import time driver = webdriver.Chrome() driver.maximize_window() driver.get('https://www.toutiao.com/') driver.implicitly_wait(10) driver.find_element_by_link_tex