爬取今日头条图片(解决缩略图问题+MySQL)

1. 引言

  针对python爬虫—分析Ajax请求对json文件爬取今日头条街拍美图中存在的爬取图片为缩略图以及图片不全的问题,本文做出如下改进:
  (1) 爬取网页全部的图片;
  (2) 爬取原始图片;
  (3) 将图片url存储到MySQL。

  作者处于爬虫入门阶段,可能有些部分不是很准确,恳请各位批评指正。

2. 分析

2.1 获取主页的url

图1
图2

2.2 获取当前页所有文章的链接

在这里插入图片描述   上图是当前页所有文章的具体信息,共20条数据。 在这里插入图片描述
  点开其中的一条,"article_url"即原文的url。
在这里插入图片描述
  "image_list"中的数据只是对应网页的部分图片,并且为缩略图。所以我们要跳转到对应文章的url分析其中数据。

  缩略图效果:
在这里插入图片描述

2.3 具体文章的信息

在这里插入图片描述
  其中,在"pgc-img"下的"img_src"是原图的地址,所以我们要获取这些数据。

  原始图像效果:
在这里插入图片描述

  在获取img_src时,发现,采用requests.get(url).txt和BeautifulSoup等方法无法获取正确的img_src,所以采用selenium方法。

2.4 MySQL设置

  创建数据库:JRTT,建表 data11,三个字段:
  (1) id:int 20 主键 非空 自增
  (2) title:varchar 100
  (3) image:varchar 100
在这里插入图片描述

3.代码

# -*- codeing = utf-8 -*-
#@Time : 2020-12-11 13:19
#@Author : Guo
#@Fil : spider.py
#@Software : PyCharm

import json
import re
from urllib.parse import urlencode
import pymysql
from requests.exceptions import RequestException
import requests
from selenium import webdriver
import os
from hashlib import md5

headers = {
        'referer': 'https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D',
        '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',
        'x-requested-with': 'XMLHttpRequest'
        }

def get_page_index(offset, keyword):
    data = {
        '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': '1607646692776',
        '_signature': '_02B4Z6wo00f0195MhUAAAIBArYVsuw9LjmfeSYHAAKhKgV6P8VnGt8BgGfYqBzurBqNVSPjaCMcZ0577a6yeYsB1mU38awHzZTSOceC.rPC5xdL3o.MNfhlP4pPWgKCvXsqylAdmhUUfXHP52b'
    }
    url = 'https://www.toutiao.com/api/search/content/?' + urlencode(data)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print("请求索引页失败")
        return None

# 获取当前页所有文章的链接 article_url
def parse_page_index(html):
    data = json.loads(html)
    for item in data.get('data'):
        if 'article_url' in item.keys() and item['article_url'] != []:
            yield item.get('article_url')

# 具体访问每一个文章
def get_page_detail(url):
    # option = webdriver.ChromeOptions()
    # option.add_argument('headless')  # 设置option
    # browser = webdriver.Chrome(options=option)  # 调用带参数的谷歌浏览器
    browser = webdriver.Chrome()
    browser.get(url)
    html = browser.page_source
    browser.close()
    return html

# 解析详情页
def parse_page_detail(html):
    title_pattern = re.compile('<title>(.*?)</title>')
    images_pattern = re.compile('<div class="pgc-img">.*?<img src="(.*?)".*?>', re.S)
    result_title = re.search(title_pattern, html).group(1)
    result_images = re.findall(images_pattern,html)
    if result_images and result_title:
        for i in range(len(result_images)):
            yield {
                'title': result_title,
                'image': result_images[i]
            }

def get_conn():
    conn = pymysql.connect(host="127.0.0.1",
                           user="root",
                           password="输入MySQL的密码",
                           db="JRTT")
    cursor = conn.cursor()
    return conn, cursor

def close_conn(conn, cursor):
    cursor.close()
    conn.commit()
    conn.close()

def save_to_mysql(result):
    conn, cursor = get_conn()
    if result!= None:
        a = [result.get('title'), result.get('image')]
        sql = "insert into data11(title, image) values(%s,%s)"
        cursor.execute(sql, (a[0], a[1]))
    close_conn(conn, cursor)


def save_image(item):
    if not os.path.exists(item.get('title')):#判断当前文件夹下是否有该文件
        os.mkdir(item.get('title'))#如果不存在就创建该文件夹
    try:
        response = requests.get(item['image']) #get函数获取图片链接地址,requests发送访问请求,上面那个字典
        if response.status_code==200: # 访问成功 进行下一步操作
            file_path='{0}/{1}.{2}'.format(item.get('title'),md5(response.content).hexdigest(),'jpg')
            # md5摘要算法(哈希算法),通过摘要算法得到一个长度固定的数据块。将文件保存时,通过哈希函数对每个文件进行文件名的自动生成。
            # md5() 获取一个md5加密算法对象
            # hexdigest() 获取加密后的16进制字符串
            if not os.path.exists(file_path):
                with open(file_path,'wb') as f:
                    f.write(response.content)
                print('Downloaded image path is: ', file_path)
            else:
                print('Already Dowloaded',file_path)
    except requests.ConnectionError:
        print('Failed to Save Image')


def main():
    for offest in range(0,20,20):   # 定义爬取的范围
        html = get_page_index(offest,"街拍")
        for url in parse_page_index(html):
            html = get_page_detail(url)
            if html:
                result = parse_page_detail(html)
                for i in result:
                    save_image(i)  # 保存到本地 
                    save_to_mysql(i)  # 保存到mysql

if __name__ == '__main__':
    main()

4. 效果

4.1 本地效果图

在这里插入图片描述

4.2 MySQL效果图

在这里插入图片描述

参考:

[1] python爬虫—分析Ajax请求对json文件爬取今日头条街拍美图.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值