吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6873|回复: 28
收起左侧

[Python 转载] Python之如何优雅的下载一堆小哥哥图片

[复制链接]
763221847 发表于 2018-6-8 16:22
本帖最后由 763221847 于 2018-6-8 20:35 编辑

简介:
话不多说,本文章直接介绍如何粗暴的用Python抓一波小哥哥
使用到的技术有:
使用到的库有:os, re, sqlite3, time, requests, lxml
Sqlite数据库名: data.db
...

第一步 确定目标

1. 文字信息

分类标题标签URL

2. 图片信息

主图、小哥哥页内图

第二步 分解目标

1. 分析特征:
  • 入口信息披露

Snip20180607_65.png

  • 分类信息披露

Snip20180607_67.png Snip20180607_68.png

  • 标签信息披露

Snip20180607_69.png Snip20180607_70.png

  • 小哥哥页内信息披露

    Snip20180607_71.png Snip20180607_72.png

通过上面的图片分析出以下特征:

下面使用的是浏览器开发工具查看/审查元素

  • 分类DOM
    Snip20180607_73.png
  • 标签DOM
    Snip20180607_74.png
  • 小哥哥DOM
    Snip20180607_75.png
2. 建立模型

通过上面的特征开始建立模型:

需要先建立好sqlite数据库:
Snip20180608_78.png Snip20180608_79.png Snip20180608_80.png

2.1. 分类页信息

开始页面处元素节点为<div class="nav_nav">下的所有<li>标签内的<a>节点的href属性和文字信息为分类信息存放位置
Ps. 剔除URL不包含www.shuaia.net的内容

2.2. 标签页信息

开始页面处元素节点为<div id="hot-tags">下的所有<li>标签内的<a>节点的href属性和文字信息为标签信息存放位置

2.3. 小哥哥信息
  • a. 分类页小哥哥

    • 循环所有分类页码获取小哥哥URL
      信息存放在: 分类页处元素节点为<div id="content">下的所有<div>标签内<a class="item-img">节点的href属性、<img class='attachment-weiran'>节点的src属性
  • b. 标签页小哥哥

    • 循环所有标签页码获取小哥哥URL
      信息存放在: 分类页处元素节点为<div id="content">下的所有<div>标签内<a class="item-img">节点的href属性、<img class='attachment-weiran'>节点的src属性
  • c. 清洗去重, 为小哥哥加上属性

    ```py
    小哥哥 = {
    'class':...    # 分类
    'tag':...      # 标签
    'url':...      # URL地址
    'img':...      # 图片地址
    }
    ```
  • d. 获取小哥哥其它属性

    • 循环小哥哥url属性获取元素节点

      分类 = ...
      标签 = ...
      URL = ...
      标题 = <div class='wr-sigle-intro'> 内 <h1>
      发布人 = <p class='single-meta'> 内 <a>
      发布时间 = <p class='single-meta'> 内<span>
      浏览次数 = <p class='single-meta'> 内<span>
      喜欢人数 =<a class='heart-this'>

第三步 开始编写

通过分析模型开始编写代码:

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import os
import re
import sqlite3
import time

import requests
from lxml import etree
from requests.exceptions import RequestException

count = 1  # 爬取页码
count_sleep = 0.5  # 爬取延时
url_imdex = "http://www.shuaia.net/"
headers = {'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0) Gecko/20100101 Firefox/59.0"}

def getPages(urls):
    """获取页面信息"""
    print('开始获取页面信息! url=', urls)
    try:
        res = requests.get(urls, headers=headers)
        res.encoding = 'utf-8'
        if res.status_code == 200:
            return res.text
        else:
            return None
    except RequestException:
        print('获取页面信息异常! url=', urls)
        return None

def parseClass(context):
    """解析分类"""
    html = etree.HTML(context)
    items = html.xpath('//div[@class="nav_nav"]')[0]
    for item in items:
        yield{
            'class': item.xpath('a/text()')[0].split()[0],  # 分类名
            'url': item.xpath('a/@href')[0]  # 分类URL
        }

def parseTag(context):
    """解析标签"""
    html = etree.HTML(context)
    items = html.xpath('//div[@id="hot-tags"]/div/div/ul/li')
    for item in items:
        yield{
            'tag': item.xpath('a/text()')[0],  # 标签名
            'url': 'http://www.shuaia.net' + item.xpath('a/@href')[0]  # 标签URL
        }

def parseClassPages(context):
    """解析分类页面"""

    def parse_context(url):
        return getPages(url)

    index = 1
    while index <= count:
        try:
            if index == 1:
                html = parse_context(context['url'])
            else:
                html = parse_context(context['url'] + 'index_{}.html'.format(index))
            pages = etree.HTML(html)
            items = pages.xpath('//a[@class="item-img"]')
            for item in items:
                yield{
                    'class': context['class'],  # 分类名
                    'tag': None,  # 标签名
                    'img': item.xpath('img/@src')[0],  # 主图地址
                    'url': item.xpath('@href')[0]  # 小哥哥URL
                }
        except Exception:
            pass
        index += 1

def parseTagPages(context):
    """解析标签页面"""
    def parse_context(url):
        return getPages(url)

    index = 1
    while index <= count:
        try:
            html = getPages(context['url'] + '&page={}'.format(index-1))
            pages = etree.HTML(html)
            items = pages.xpath('//a[@class="item-img"]')
            for item in items:
                yield{
                    'class': None,  # 分类名
                    'tag': context['tag'],  # 标签名
                    'img': item.xpath('img/@src')[0],  # 主图地址
                    'url': item.xpath('@href')[0]  # 小哥哥URL
                }
        except Exception:
            pass
        index += 1

def parsePages(context):
    """解析小哥哥页面"""
    try:
        html = etree.HTML(context)
    except Exception:
        return None

    items = html.xpath('//div[@class="wr-single-right"]')

    def imgs(context):
        img_count = 1
        while img_count:
            if img_count == 1:
                img_html = getPages(context)
            else:
                img_html = getPages(context.replace('.html', '_' + str(img_count) + '.html'))
            if img_html is None:
                break
            imghtml = etree.HTML(img_html)
            imghtml = imghtml.xpath('//div[@class="wr-single-content-list"]/p/a/img/@src')
            for i in imghtml:
                yield 'http://www.shuaia.net' + i
            img_count += 1

    for item in items:
        yield{
            'title': item.xpath('//div[@class="wr-sigle-intro"]/h1/text()')[0],  # 标题
            'img': imgs(item.xpath('//div[@id="bdshare"]/@data')[0].split("','")[0][8:])  # 图片地址
        }

# 连接数据库
conn = sqlite3.connect('data.db')
# 获取页面信息
page_html = getPages(url_imdex)
# 解析分类信息去重储存到数据库
for i in parseClass(page_html):
    print('开始读取 {} 信息!'.format(i['class']))
    for ii in parseClassPages(i):
        cursor = conn.cursor()
        cursor.execute('select id from data where url=?', (ii['url'],))
        values = cursor.fetchall()
        cursor.close()
        if values:
            cursor = conn.cursor()
            cursor.execute('update data set class = ? where id = ?', (ii['class'], values[0][0]))
            conn.commit()
            cursor.close()
        else:
            cursor = conn.cursor()
            cursor.execute('insert into data (class, url, img) values (?, ?, ?)', (ii['class'], ii['url'], ii['img'],))
            conn.commit()
            cursor.close()
    time.sleep(count_sleep)
# 解析标签信息去重储存到数据库
for i in parseTag(page_html):
    print('开始读取 {} 信息!'.format(i['tag']))
    for ii in parseTagPages(i):
        cursor = conn.cursor()
        cursor.execute('select id from data where url=?', (ii['url'],))
        values = cursor.fetchall()
        cursor.close()
        if values:
            cursor = conn.cursor()
            cursor.execute('update data set tag = ? where id = ?', (ii['tag'], values[0][0]))
            conn.commit()
            cursor.close()
        else:
            cursor = conn.cursor()
            cursor.execute('insert into data (tag, url, img) values (?, ?, ?)', (ii['tag'], ii['url'], ii['img'],))
            conn.commit()
            cursor.close()
    time.sleep(count_sleep)

# 清空image表
cursor_del = conn.cursor()
cursor_del.execute("DELETE from image;")
conn.commit()
cursor_del.close

# 抓取保存小哥哥图片信息
cursor = conn.cursor()
cursor_re = conn.cursor()
cursor_img = conn.cursor()
cursor.execute('select id, url from data')
for url_s in cursor:
    page_html = getPages(url_s[1])
    for page in parsePages(page_html):
        cursor_re.execute('update data set title = ? where id = ?', (page['title'], url_s[0]))
        im = 0
        for img_url in page['img']:
            cursor_img.execute('insert into image (PID, img, title) values (?, ?, ?)', (url_s[0], img_url, page['title'] + "_" + str(im),))

            # 储存图片
            try:
                if not os.path.exists(page['title']):
                    os.makedirs(page['title'])
                print('图片开始保存!: {}'.format(page['title'] + "_" + str(im) + ".jpg"))
                path = os.path.join("./", page['title'])
                save_pic = path + "/" + page['title'] + "_" + str(im) + ".jpg"
                saveImg = requests.get(img_url, headers=headers).content
                with open(save_pic, 'wb') as f:
                    f.write(saveImg)
                time.sleep(count_sleep)
            except Exception:
                print('图片保存失败!: {}'.format(page['title'] + "_" + str(im) + ".jpg"))

            im += 1
        conn.commit()
cursor.close()
cursor_re.close()
cursor_img.close()

# 关闭数据库
conn.close()

第四步 写在结尾

感觉还可以优化, 如果你有好一点的建议或者问题,欢迎留言指正.嗯

SHI一样的教程, 如果没看明白一定是我没写好...


data.db.zip (73.87 KB, 下载次数: 9)

免费评分

参与人数 7吾爱币 +9 热心值 +7 收起 理由
wushaominkk + 3 + 1 鼓励转贴优秀软件安全工具和文档!
lyz88588 + 1 + 1 好好的让小白学习了很多
azw80 + 1 + 1 我很赞同!
zhoujun0814 + 1 + 1 谢谢@Thanks!
shuaiqi + 1 + 1 用scrapy爬取图片链接。再用request.get()链接。最后用f.write(r.content).
ibennie + 1 + 1 是不是可以写个 instagram 的图片下载工具?
刊登steam0 + 1 + 1 感觉很厉害,刚接触python 很多不懂。 在自学中 其次在问一个问题,大概啥时.

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 763221847 发表于 2018-6-8 20:19
刊登steam0 发表于 2018-6-8 16:38
感觉很厉害,刚接触python 很多不懂。 在自学中 其次在问一个问题,大概啥时候能入门

能实现想法就入门了...
jhsunnyshine 发表于 2018-6-11 11:33
羡慕,我也是学了python,发现自己除了会了基本语法(还是掌握不牢固的那种)什么都不会,求教该如何进行下一步
hk5858 发表于 2018-6-8 16:34
刊登steam0 发表于 2018-6-8 16:38
感觉很厉害,刚接触python 很多不懂。 在自学中 其次在问一个问题,大概啥时候能入门
夜泉 发表于 2018-6-8 16:41
楼主是一枚妹子么?

免费评分

参与人数 1吾爱币 +1 收起 理由
zuiai125520 + 1 如果不是小姐姐 那就可怕了

查看全部评分

Ocean老班长 发表于 2018-6-8 16:52
这个还是比较厉害的   支持一下
kiikjj 发表于 2018-6-8 16:56
666图片都看不到了
luanshils 发表于 2018-6-8 17:05
腐女是怎样炼成的,

ps:若楼主是男的,那么就变成了,gay是怎样炼成的
无阻 发表于 2018-6-8 17:09
为什么说py比易语言方便

看了下代码 易语言用模块做好像代码能更少..
lanail 发表于 2018-6-8 17:17
楼主发的图片不显示啊
WqiancangQ 发表于 2018-6-8 17:25
学习中学习中学习中
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 01:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表