用Python编写一个简单的爬虫

做者信息:html

Author : 黄志成(小黄)

博客地址: 博客vue

呐,这是一篇福利教程.为何这么说呢.咱们要爬取的内容是美图网站(嘿嘿,老司机都懂的)mysql

废话很少说.开始今天的表演.web

这个图集网站不要问我怎么来的.绝对不是我刻意找的.(实际上是看了别的发的一篇文章,就想本身动手实现一下)redis

咱们今天的任务就是 将这些图集保存下来。sql

首先咱们须要获取到全部的列表,咱们往下拉动滚动条,拉到底,会继续自动加载内容,咱们经过浏览器的NetWork能够发现请求的数据包json

咱们来分析一下这个数据包浏览器

URL:https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=3&from=gallery

经过url咱们能够知道几个重要的参数多线程

offset 偏移量
count 数量
cur_tab 当前分类

这里不少朋友可能对偏移量不太了解,这里我用sql语句表示一下,若是了解sql的朋友 确定就知道了函数

mysql> SELECT * FROM art LIMIT offset , count

mysql> SELECT * FROM table LIMIT 5,10;  // 检索记录行 6-15

mysql> SELECT * FROM table LIMIT 95,1; // 检索记录行 96

这里我每次读取一条,对一条进行操做.

URL:https://www.toutiao.com/search_content/?offset=1&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=1&cur_tab=3&from=gallery

每次对offset 进行自增便可了

咱们点击进去 看看数据的结构.

咱们须要获取到该图集的连接。

进入这篇图集,在NetWork中并无发现图集有关的请求接口,可能也是混排的.

咱们能够查看页面的源码

原来真的是混排的写法.看了一下这里用到vue.具体怎么实现的咱们不去探讨了,咱们只须要取出数据便可。

那如何取出呢? 提供两种方法,一种就是正则,一种就是本身写一个取文本的函数.这里我用第二种做为演示,下面是取文本的函数.

def txt_wrap_by(start_str, end, html):
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()

咱们取出 JSON.parse("") 中的数据

观察数据,能够发现 咱们取出 url 就能够了,这里的数据是json可是被转义了,咱们就经过正则取出吧

正则的语法如图上,最后我也会放出全部代码滴,你们放心.

取到了uri 咱们只要在前面拼上 http://p3.pstatp.com/ 便可.

而后保存为图片便可~

上面说的都是思路,最后放出代码~

import requests,os,json,re,datetime

# 主函数
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 = 'http://www.toutiao.com/search_content/?offset=' + str(n) + '&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=1&cur_tab=3&from=gallery'
        re = requests.get(url)
        data = re.json()['data']
        if not data:
            break
        # 运行图片下载函数
        download_pic(data[0]['article_url'],n)
        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/'
    # 这里必须带上协议头,不然会请求失败
    header = {
        '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)
    content = res.text
    img_list_json = txt_wrap_by('gallery: JSON.parse("','"),',content)
    # 正则获取全部的uri
    img_list = re.findall(r'uri\\":\\"(.*?)\\"',img_list_json)
    #判断是否有此目录
    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:
        img_path = download_pic_url + v
        img_path = img_path.replace("\\", "")
        # 读取图片
        atlas = requests.get(img_path).content
        # 保存图片
        with open( './img/' + str(n) + '/' + str(datetime.datetime.now()) +'.jpg', 'wb') as f:  # 把图片写入文件内
            f.write(atlas)


# 取出两个文本之间的内容
def txt_wrap_by(start_str, end, html):
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()

# 运行程序
main()

最后 展现一下 运行结果:

这个程序还有许多不完善的地方,我会在以后教程加入 redis 和 多线程 的写法,让他成为最快的爬虫~

敬请期待~ 今天就到这里了. 又是周末!祝你们周末愉快。嘿嘿~ 看个人美图去了。

相关文章
相关标签/搜索