爬取动漫表情包

# coding:utf-8

# 设计思路:1.找到目标信息所在的json数据2.通过方法从json数据筛选出目标信息链接3.文件操作,下载加保存
# 这个爬虫流程:第一步,访问网站,是否有需要的信息数据,没有就修改请求数据;第二步,伪装浏览器,获取所需json数据,
# 然后通过方法筛选出目标信息链接3.文件操作,下载加保存,回到第一步,并修改请求参数。
import requests, os, json, re, uuid


# 主函数
def main():
    foreach_art_list()


def foreach_art_list():
    # 判断目录下是否存在jilv.txt文件 如果存在则读取里面的数值
    if os.path.exists('./jilv.txt'):
        f = open('./jilv.txt')
        n = f.read()
        n = int(n)
        f.close()
    else:
        n = 1
    while True:
        url = 'https://www.toutiao.com/search_content/?offset=' + str(
            n) + '&format=json&keyword=动漫表情包&autoload=true&count=1&cur_tab=3&from=gallery'
        # keyword关键字就不说了,加不加引号关系不大 count是相对于offset的偏移量,一堆自己设置的参数
        r = requests.get(url)
        # get请求
        # print(type(r))
        # print(r)
        # r = requests.get(url),r是一个requests对象,r.content.decode()才是获取的页面内容,
        # 然后用json.loads(  # decode()解码后的json)把获取的json处理成python字典,最后再用["data"]来提取内容
        # 另一种写法的得到的a与(r.json)相同,只是a为字符串
        # a =r.content.decode()
        # print(type(a))
        # r = json.loads(a)
        # print(type(r))
        # data = r.json()['data']
        # 这两种都是通过字典键来取值

        data = r.json().get('data')
        # print(r.json())
        # r.json()是字典,返回响应的json编码的内容,如果有的话
        # print(type(r.json()))
        # 由字典组成的列表
        # data是由字典组成的列表
        # print(data)
        # data非空
        if not data:
            # print(type(data))
            break
        # 运行图片下载函数
        download_pic(data[0]['article_url'], n)
        # print(data[0])
        # print(data[0]['article_url'])
        n = n + 1
        # 将n写入文件 防止程序运行出错 可以继续运行
        with open('./jilv.txt', 'w') as f:
            f.write(str(n))


def download_pic(url, n):
    download_pic_url = 'http://p3.pstatp.com/'
    # 这里必须带上协议头,否则会请求失败

    # 请求头其实最关键的就是这个user-agent,接受数据的服务端利用user-agent来判断用户环境的
    header = {
        # 伪装成windows的头
    'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
        #伪装成mac的头
    # 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
    }


    res = requests.get(url, headers = header)
    # print(res)
    # 获取请求后的text文件
    content = res.text
    # print(type(content))
    # content为包含html文件的字符串
    img_list_json = txt_wrap_by('gallery: JSON.parse("', '"),', content)
    # img_list_json为包含图片链接的json数据

    # 正则获取所有的uri,匹配的是未转义的img_list_json,不是转义后的
    img_list = re.findall(r'uri\\":\\"(.*?)\\"',img_list_json)
    # 有个小细节,json数据print时或自动转义(未证实)
    # print (type(img_list_json))
    # print(img_list_json)
    # print(img_list)
    # 判断是否有此目录
    if 'img' not in os.listdir('.'):
        os.mkdir('./img')
    if str(n) not in os.listdir('./img'):
        os.mkdir('./img/' + str(n))
    for v in img_list:
        # print(v)
        # print(img_list)
        # v就是图片链接,网上仓库的绝对路径位置
        img_path = download_pic_url + v
        #这里实际上是换的四个斜杠,虽然replace只写了两个斜杠,传进去相当于换了四个
        img_path = img_path.replace("\\", "")
        # \\表示windows下级目录
        # 读取图片
        atlas = requests.get(img_path).content
        # 保存图片
        with open('./img/' + str(n) + '/' + str(uuid.uuid1()) + '.jpg', 'wb') as f:  # 把图片写入文件内
            f.write(atlas)


# 取出JSON.parse()之间的内容
def txt_wrap_by(start_str, end, html):
    # html就是content
    # start_str的值为'gallery: JSON.parse("'
    # print(start_str)
    # end为'"),'
    start = html.find(start_str)
    # 找到的start在4982位,
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        # end在10826位
        # 找到gallery结束的位置
        if end >= 0:
            # end在10826位
            #     print(html)
            #     print(type(html))
            #     print(type(html[start:end]))
            #     print(html[start:end].strip())
                return html[start:end].strip()
        # html[start:end].strip()为单个字典构成的字符串,这个字典是json数据


# 运行程序
main()

猜你喜欢

转载自blog.csdn.net/qq_28070007/article/details/80301425