Ajax爬取今日头条街拍改进——各种雷区解决包括data:none问题

Ajax爬取今日头条街拍改进——各种雷区解决包括data:none问题

本虫正在自学爬虫为大数据做准备,由于时代的进步各网站都加强了反爬措施,而在学习过程中书本上的教学已经不适用了,本虫在学习过程中将代码稍微改进了一下但是还有BUG,还希望各位大佬多多指点。

网页分析:

进入页面我们打开F12点击XHR(Ajax加载的数据在这里面能找到)试着点开这些数据,然后点击Preview可以发现第一个数据的data有我们想要的数据,点开分析代码。
在这里插入图片描述data里面有很多数据但是我们可以现在0里面的数据不是我们想要的,在写代码 的时候可以跳过它,再继续看剩下的代码,可以发现image_list里面有我们要找的图片的url在这里插入图片描述在这里插入图片描述我们拖动进度条发现越来越多的数据加载出来,我们点开发现他们的基本结构和刚刚看到的数据相似,分析其URL可以知道他们的offset参数不同,就可以看出这些数据就相当于他们的页面,连起来就可以提取想要的数据啦!在这里插入图片描述

编写神奇的代码

有些虫虫发现拿到了数据的Request URL用代码请求发现data:none,无法请求到数据,不知道虫虫们有没有发现有时候刷新页面的时候偶尔会有一个图形验证码,这就是关键所在,我们把请求头里面在多加几个信息进去,cookie,referer等等 。
我们再次请求就会发现ok了。
我们这里运用from urllib.parse import urlencode ,构造url 为了更加的保险url上的时间戳timestamp直接用int(time.time())来获取,这样就可以构造出一个完整的URL,请求下来也是轻轻松松啦!

注:有些虫友会在url上的路径和参数动手,虽然能请求到数据,但是早已不是你想要的那个人儿(网站)啦!

def get_page(offset):
    headers={
    
    
        'cookie': 'tt_webid=6788065855508612621; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6788065855508612621; csrftoken=495ae3a5659fcdbdb78e255464317789; s_v_web_id=k66hcay0_qsRG7emW_x2Qj_4R3o_AeAG_iT4JWmz83jzr; __tasessionId=23dn3qk0f1580738708512',
        'referer': 'https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
        'x-requested-with': 'XMLHttpRequest'
    }#有隐形的图片验证,偶尔出现,cookie是重要参数 这是解决data:none的关键    
    params={
    
    
        'aid': '24',
        'app_name': 'web_search',
        'offset': offset,
        'format': 'json',
        'keyword': '街拍',
        'autoload': 'true',
        'count': 20,
        'en_qc': 1,
        'cur_tab': 1,
        'from': 'search_tab',
        'pd': 'synthesis',
        'timestamp':int(time.time())             #获取时间戳
    }#采用构造url方式更加简洁明了,后期易于修改
    url = 'https://www.toutiao.com/api/search/content/?' + urlencode(params)
    json = requests.get(url, headers=headers).json()  # 列表0,1,2,3......
    return json

这里本虫可是煞费了功夫啊,调试了很多遍。因为data里面的列表有几个没有image_list的,那些没有image_list的列表里面有些装着乱七八糟的东西,像什么用户的信息啊什么的。
既然如此,我们就直接获取image_list里面的图片,用条件语句筛选出来,然后构造一个生成器返回出来。

def get_image(json):
    for item in json['data']:
        if 'image_list' in item:
            title = item['title']
            for image_urls in item['image_list']:
                image_url = image_urls['url']
                yield{
    
    
                    'image':image_url,
                    'title':title
                }
def save_image(content):
    if not os.path.exists(content['title']):
        if '|' in content['title']:
            c_title = content['title'].replace(' | ','')#有些title里面有特殊符号无法用其名创建文件夹
            os.mkdir(c_title)
        else:
            os.mkdir(content['title'])
    response = requests.get(content['image'])
    if response.status_code == 200:
        file_path = '{0}/{1}.{2}'.format(content['title'].replace(' | ','')if '|' in content['title'] else content['title'],md5(response.content).hexdigest(),'jpg')#文件的名字和地址,用三目运算符来调试文件夹的名字
        if not os.path.exists(file_path):
            with open(file_path,'wb')as f:
                f.write(response.content)
        else:
            print('已下载',file_path)
if __name__ == '__main__':
    for i in range(6,8):
        offset = i*20           #构造Ajax加载的offset
        print(offset)
        json=get_page(offset)
        for content in get_image(json):
            try:
                save_image(content)
            except FileExistsError and OSError:
                print('文件夹创建名格式错误:包含特殊字符')#由于实验需要就直接跳过了那些不必要的错误
                continue

完整代码:

import requests
from urllib.parse import urlencode
import time
import os
from hashlib import md5

def get_page(offset):
    headers={
    
    
        'cookie': 'tt_webid=6788065855508612621; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6788065855508612621; csrftoken=495ae3a5659fcdbdb78e255464317789; s_v_web_id=k66hcay0_qsRG7emW_x2Qj_4R3o_AeAG_iT4JWmz83jzr; __tasessionId=23dn3qk0f1580738708512',
        'referer': 'https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
        'x-requested-with': 'XMLHttpRequest'
    }#有隐形的图片验证,偶尔出现,cookie是重要参数 这是解决data:none的关键
    params={
    
    
        'aid': '24',
        'app_name': 'web_search',
        'offset': offset,
        'format': 'json',
        'keyword': '街拍',
        'autoload': 'true',
        'count': 20,
        'en_qc': 1,
        'cur_tab': 1,
        'from': 'search_tab',
        'pd': 'synthesis',
        'timestamp':int(time.time())             #获取时间戳
    }#采用构造url方式更加简洁明了,后期易于修改
    url = 'https://www.toutiao.com/api/search/content/?' + urlencode(params)
    json = requests.get(url, headers=headers).json()  # 列表0,1,2,3......
    return json
def get_image(json):
    for item in json['data']:
        if 'image_list' in item:
            title = item['title']
            for image_urls in item['image_list']:
                image_url = image_urls['url']
                yield{
    
    
                    'image':image_url,
                    'title':title
                }
def save_image(content):
    if not os.path.exists(content['title']):
        if '|' in content['title']:
            c_title = content['title'].replace(' | ','')#有些title里面有特殊符号无法用其名创建文件夹
            os.mkdir(c_title)
        else:
            os.mkdir(content['title'])
    response = requests.get(content['image'])
    if response.status_code == 200:
        file_path = '{0}/{1}.{2}'.format(content['title'].replace(' | ','')if '|' in content['title'] else content['title'],md5(response.content).hexdigest(),'jpg')#文件的名字和地址,用三目运算符来调试文件夹的名字
        if not os.path.exists(file_path):
            with open(file_path,'wb')as f:
                f.write(response.content)
        else:
            print('已下载',file_path)
if __name__ == '__main__':
    for i in range(6,8):
        offset = i*20           #构造Ajax加载的offset
        print(offset)
        json=get_page(offset)
        for content in get_image(json):
            try:
                save_image(content)
            except FileExistsError and OSError:
                print('文件夹创建名格式错误:包含特殊字符')
                continue

总结

本虫根据《python3网络爬虫开发实战》对代码的改进,希望各位虫友多多指出不足,本虫也会不断加油的!希望全国疫情越来越好,我相信新型冠状病毒一定会被我们消灭的!!!加油!中国!

猜你喜欢

转载自blog.csdn.net/qq_44627822/article/details/104211941
今日推荐