ZeroNet Blogs

Static ZeroNet blogs mirror

python学习小记

- Posted in 贪吃的猫 by with comments

我对Python感兴趣的原因是想要用Python来写爬虫,用来爬一些数据(最主要的是sfacg的图书元数据 它的搜索太让人抓狂了!!!)。

然后我就开始学Python

先看的是Python 2.7教程 - 廖雪峰的官方网站,看了大半感觉掌握了一些Python知识,可以写一些简单的东西了。然后开始看爬虫方面的知识,看的是Python爬虫学习系列教程,按照上面的一篇篇的学,基本上刷了一遍。

然后开始动手。

写了一些小脚本用来爬数据book.sfacg.com,开始的时候从目录页爬,然后发现结果不全,而且封面也都是一些小图(要的就是封面),这可不行。

然后准备上框架,然后开始学Scrapy框架,没有在网上发现好的教程,主要是自己看它的官方文件,边看边写,遇到问题了就上网搜。后来发现中文翻译的已经有些落后了,就开始看英文的官方文本,发现基本和用的软件版本对的上,没有什么问题。

后来基本上写完了,bug也不完了后,然后就觉得自己的任务终于完了,一种空虚感。

后来有写了一个爬iqing.in的爬虫,这个是爬全文的。

当然,练习的时候也写了一些小作品练了练手。

现在学业繁忙,准备放下这些杂业,所以今天写文总结一下。

写的几个成熟的作品也发出来让大家看看。(新手,不要见笑啊!)

PS:一些小作品

目录:

  • 跟踪路由并现实ip归属地的小脚本
  • 代理爬虫
  • sfacg 爬虫
  • iqing.in 爬虫

跟踪路由并现实ip归属地的小脚本

#!/usr/bin/env python2
# -*- coding:utf-8 -*-

__author__='YYW'

import requests
import re
import sys
import commands

class IPlocation(object):
    def __init__(self):
        self.patten = re.compile(r'(((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?))')
        self.ips = []
        self.webstatus = 403
        self.trace = ''
        self.input = sys.argv

    def tracerouter(self, input):
       if len(input) == 2:
           t = commands.getoutput('traceroute -n ' +str(input[1]))
           self.trace = t
       else:
           print('请输入IP或域名')
           exit()

    def dealdata(self):#处理输出ips
        o = self.trace
        ips = re.findall(self.patten, o)
        self.ips = ips
        return None

    def query_ip(self, ip):#利用ipip.net api 查询地址
        payload = {'ip': ip}
        r = requests.get("http://freeapi.ipip.net/", params=payload)
        self.webstatus = r.status_code
        return r.text

    def netest(self):#网络检测
        temp = self.query_ip('8.8.8.8')
        nettest = re.search("202.204.32.54", temp)
        if nettest:
            print('未连接校园网,请检查网络')
            exit()

    def start(self):
        self.netest()
        self.tracerouter(self.input)
        print(self.trace)
        self.dealdata()
        i = -1
        if self.input[1][:1] in [str(x) for x in range(10)]:
            m = 1
        else:
            m = 0
        print('\n路由跟踪:')
        for ipt in self.ips[m:]:
            i = i + 1
            ip = ipt[0]
            ipq = self.query_ip(ip)
            while self.webstatus != 200:
                ipq = self.query_ip(ip)
            print('%d\t%s\t%s' % (i, ipt[0], ipq))  

s = IPlocation()
s.start()

代理爬虫

items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# <http://doc.scrapy.org/en/latest/topics/items.html>

import scrapy


class HttpProxiesItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    proxie_ip = scrapy.Field()
    #proxie_type = scrapy.Field()
    proxie_location = scrapy.Field()

spider (proxies_spiders.py)

# -*- coding: utf-8 -*-

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from http_proxies.items import HttpProxiesItem
from scrapy.linkextractors import LinkExtractor
import re

class Http_proxie_spider(CrawlSpider):
    name = 'http_proxies'
    allowed_domains = ['youdaili.net']
    start_urls = ['http://www.youdaili.net/Daili/http/']
    rules = (
        Rule(LinkExtractor(allow=('/Daili/http/list_\d+.html'))), 
        Rule(LinkExtractor(allow=('/Daili/http/\d+.html')), callback='parse_item')
    )

    def parse_item(self, response):
        self.log('Hi, this is an item page! %s' % response.url)

        patten = re.compile(r'(((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?):\d+)@(\w+)#(.*?)<')
        t = re.findall(patten, response.text)
        proxie_ips = [t[x][0] for x in range(len(t))]
        proxie_types = [t[x][-2] for x in range(len(t))]
        proxie_locations = [t[x][-1] for x in range(len(t))]
        item = HttpProxiesItem()
        for i in range(len(proxie_ips)):
            item['proxie_ip'] = proxie_ips[i]
            #item['proxie_type'] = proxie_types[i]
            item['proxie_location'] = proxie_locations[i]
            yield item

sfacg爬虫

items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# <http://doc.scrapy.org/en/latest/topics/items.html>

import scrapy


class SfacgItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    bookid = scrapy.Field()
    bookname = scrapy.Field()
    author = scrapy.Field()
    word_number = scrapy.Field()
    view_time = scrapy.Field()
    sum_point = scrapy.Field()  #总评分
    point = scrapy.Field()  #评分具体
    bookMarknum = scrapy.Field() #类型
    favSticks = scrapy.Field()  #赞
    pointUserCount = scrapy.Field() #评分人数
    type = scrapy.Field()   #类型
    update_time = scrapy.Field()
    brief_introduction = scrapy.Field()
    cover = scrapy.Field()
    cover_time = scrapy.Field()
    cover_status = scrapy.Field()
    cover_path = scrapy.Field()
    MonTicketNum = scrapy.Field()
    Tags = scrapy.Field() #<type 'list'>,<type 'dict'>
    is_VIP = scrapy.Field()
    VIP_time = scrapy.Field()
    hav_beitou = scrapy.Field()
    left_beitou = scrapy.Field()
    left_beitou_time = scrapy.Field()
    left_beitou_status = scrapy.Field()
    left_beitou_path = scrapy.Field()
    right_beitou = scrapy.Field()
    right_beitou_time = scrapy.Field()
    right_beitou_status = scrapy.Field()
    right_beitou_path = scrapy.Field()
    status = scrapy.Field() #状态
    sumNumbook = scrapy.Field()#共有X本书
    max_page = scrapy.Field()#共有X页
    brief_commen_num = scrapy.Field() #短评数
    long_commen_num = scrapy.Field() #长评数
    text_time = scrapy.Field()

setting.py

# -*- coding: utf-8 -*-

# Scrapy settings for sfacg project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     <http://doc.scrapy.org/en/latest/topics/settings.html>
#     <http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html>
#     <http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html>

BOT_NAME = 'sfacg'

SPIDER_MODULES = ['sfacg.spiders']
NEWSPIDER_MODULE = 'sfacg.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 96
#CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See <http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay>
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
TELNETCONSOLE_ENABLED = True
TELNETCONSOLE_PORT = '6321'

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
   'Accept-Language': 'zh',
}

# Enable or disable spider middlewares
# See <http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html>
#SPIDER_MIDDLEWARES = {
#    'sfacg.middlewares.MyCustomSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See <http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html>
DOWNLOADER_MIDDLEWARES = {
    'sfacg.middlewares.Test': 543,
}

# Enable or disable extensions
# See <http://scrapy.readthedocs.org/en/latest/topics/extensions.html>
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': 300,
##    'scrapy.extensions.feedexport.FeedExporter': 500,
#}

# Configure item pipelines
# See <http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html>
ITEM_PIPELINES = {
#    'sfacg.pipelines.Pre_deal': 200,
    'sfacg.pipelines.Save_image': 300,
#    'sfacg.pipelines.JsonWriterPipeline': 400
#    'sfacg.pipelines.Csv_Writer':400
}
#LOG_LEVEL = 'ERROR'
LOG_LEVEL = 'INFO'
#LOG_LEVEL = 'DEBUG'
IMAGES_STORE = '/srv/xxx'
#IMAGES_EXPIRES = 90

# Enable and configure the AutoThrottle extension (disabled by default)
# See <http://doc.scrapy.org/en/latest/topics/autothrottle.html>
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See <http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings>
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'

#Feed exports
FEED_URI = 'file:///srv/xxx.json'
FEED_FORMAT = 'json'
#CSV_STORE = '/srv/xxx.csv'
#JSON_STORE = '/srv/xxx.json'
#FEED_URI = 'file:///srv/xxx.csv'
#FEED_FORMAT = 'csv'

piplines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: <http://doc.scrapy.org/en/latest/topics/item-pipeline.html>

#from scrapy.pipelines.images import ImagesPipeline
#from scrapy.exceptions import DropItem
#import json
from sfacg import settings
from hashlib import md5
import time, os,  requests

class Save_image(object):
    def __init__(self):
        self.dir_path = settings.IMAGES_STORE
#        self.session = requests.Session()

    def download_img(self, item, name):#下载图片
        request_url = item[name]
        checksun = md5(request_url.encode('utf-8')).hexdigest()
        #创建session,修改包头
        s = requests.Session()
        headers={
#        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
        'Referer': 'http://book.sfacg.com/Novel/%s/' % str(item['bookid'])
        }
        s.headers.update(headers)
        #下载
        try:
            img = s.get(request_url, timeout = 5, stream=True)
        except Exception:
            try:
                img = s.get(request_url, timeout = 5, stream=True)
            except Exception:
                item['%s_status' % name] = False
                return item
        finally:
            if img.status_code == 200:
                img_type= os.path.splitext(request_url)[-1]
                path = '%s/%s/%s/%s%s' % (self.dir_path, name, checksun[:2], checksun, str(img_type))
                t_c = img.content
                #写入文件
                with open(path, 'wb') as f:
                    f.write(t_c)
                #返回状态
                now_time = time.ctime()
                item['%s_status' % name] = True
                item['%s_time' % name] = now_time
                item['%s_path' % name] = checksun
                return item
            else:
                item['%s_status' % name] = False
                return item

    def isexists(self, item, name):
        request_url = item[name]
        checksun = md5(request_url.encode('utf-8')).hexdigest()
        img_type= os.path.splitext(request_url)[-1]
        path = '%s/%s/%s/%s%s' % (self.dir_path, name, checksun[:2], checksun, str(img_type))
        dir_path = '%s/%s/%s' % (self.dir_path, name, checksun[:2])
        isExist_dir = os.path.exists(dir_path)
        if not isExist_dir:
            os.makedirs(dir_path)
        isExists = os.path.exists(path)
        if isExists:
            item['%s_path' % name] = checksun
            return [item, isExists]
        else:
            return [item, isExists]

    def mkdir(self):
        cover_path = '%s/%s' % (self.dir_path, 'cover')
        left_beitou_path = '%s/%s' % (self.dir_path, 'left_beitou')
        right_beitou_path = '%s/%s' % (self.dir_path, 'right_beitou')
        if not os.path.exists(self.dir_path):
            os.mkdir(self.dir_path)
        for x in [cover_path, left_beitou_path, right_beitou_path]:
            if not os.path.exists(x):
                os.mkdir(x)
        return

    def process_item(self,item, spider):
        self.mkdir()
        if item.get('cover'):
            #cover
            t = self.isexists(item,'cover')
            item = t[0]
            if not t[1]:
                item = self.download_img(item,'cover')
            #beitou
            if item['hav_beitou'] :
                t = self.isexists(item,'left_beitou')
                item = t[0]
                if not t[1]:
                    item = self.download_img(item,'left_beitou')
                t = self.isexists(item,'right_beitou')
                item = t[0]
                if not t[1]:
                    item = self.download_img(item,'right_beitou')
                return item
            else:
                return item
        else:
            return item

middleware.py

# -*- coding: utf-8 -*-

#from scrapy.exceptions import IgnoreRequest
#from scrapy.contrib.downloadermiddleware import DownloaderMiddleware
import time
import re

class Test(object):
    def __init__(self):
        self.T = {}

    def get_bookid(self, request):
        bookid = int(re.findall(r'Novel/(\d+\d)', str(request.url))[0])
        return bookid

    def process_request(self,request,spider):
        if re.search(r'Novel/\d+\d','request.url'):        
            now_time = time.time()
            bookid = self.get_bookid(request)
            if self.T.get('%d' % bookid) == None:        
                self.T['%d' % bookid] = now_time
                return None
            elif now_time - self.T['%d' % bookid] >= 10800 :
                return None
            else:
                raise IgnoreRequest("The novel is't update")
        else:
            return None

spider.py

# -*- coding: utf-8 -*-

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from sfacg.items import SfacgItem
import re, requests, time, random

class SfacfgSpider(CrawlSpider):
    name = 'sfacg'
    rules=(
        Rule(LinkExtractor(allow=('/List/default.aspx?PageIndex=\d+'))),
        Rule(LinkExtractor(allow=('/Novel/\d+/'),deny=('/List/default.aspx?PageIndex=\d+')),callback='detail_parse')
        )
    allowed_domains = ['sfacg.com']
    start_urls = ['http://book.sfacg.com/List/']

    def test_url(self, url):#检查url
        if re.match(r'^/', url):
            out = 'http://book.sfacg.com' +str(url)
        else:
            out = url
        return out

    def parse_start_url(self, response):#初始化下载,获得总页数、总书籍数
        max_page = int(response.xpath('//div[@class="list_pages"]/ul[@class="nav pagebar"]/li[last()-1]/a/text()').extract()[0])
        sumNumbook = int(response.xpath('//div[@class="list_pages"]/div[@class="page_l"]/span/text()').extract()[0])
        page_baseurl = 'http://book.sfacg.com/List/default.aspx?PageIndex='
        Item = SfacgItem()
        Item['bookid'] = 0
        Item['bookname'] = 'sum'
        Item['text_time'] = time.ctime()
        Item['sumNumbook'] = sumNumbook
        Item['max_page'] = max_page
        t = requests.post("http://book.sfacg.com/ajax/ashx/Common.ashx?op=getunlockhour", {'nid': 44068})
        Item['VIP_time'] = int(re.findall(r'(\d+)', t.text)[0])
        yield Item
        for page_url in [page_baseurl +str(i) for i in range(max_page+1)[1:]]:
            yield scrapy.Request(page_url)

    def detail_parse(self, response):#书籍信息获得
        bookid = int(re.findall(r'Novel/(\d+\d)', str(response.url))[0])
        Item =SfacgItem()
        Item['text_time'] = time.ctime()
        ##静态部分获取
        Item['bookid'] = bookid
        Item['bookname'] = response.xpath('//ul[@class="synopsises_font"]/li[1]/img/@alt').extract()[0]
        Item['author'] = response.xpath('//ul[@class="synopsises_font"]/li[2]/a/text()').extract()[1]
        Item['word_number'] = response.xpath('//ul[@class="synopsises_font"]/li[2]/span/text()').extract()[4]
        Item['type'] = response.xpath('//ul[@class="synopsises_font"]/li[2]/a/text()').extract()[0]
        commen_num = response.xpath('//span[@class="content_title"]/span/a/text()').re('\d+')
        l_c = len(commen_num)
        if  l_c == 0:       
            Item['brief_commen_num'] = 0
            Item['long_commen_num'] = 0
        elif l_c == 1:
            Item['brief_commen_num'] = int(commen_num[0])
            Item['long_commen_num'] = 0
        else:
            Item['brief_commen_num'] = int(commen_num[0])
            Item['long_commen_num'] = int(commen_num[1])
        #VIP
        if response.xpath('//ul[@class="synopsises_font"]/descendant::img/@src').re('vip.gif'):
            is_VIP = True
        else:
            is_VIP = False
        Item['is_VIP'] = is_VIP
        b = response.xpath("//ul[@class='synopsises_font']/li[2]/child::text()").extract()
        i = 0
        while b[i] == u'\r\n' or b[i] == u'\r\n\r\n':
            i = i + 1
        if i >= 5:
            Item['brief_introduction'] = ''
        else:
            Item['brief_introduction'] = b[i]
        Item['update_time'] = response.xpath('//ul[@class="synopsises_font"]/descendant::text()').re('(\d{4}.+\d\d)')[-1]
        Item['status'] = response.xpath('//ul[@class="synopsises_font"]/li[2]/descendant::text()').re('\[(.*)\]')[-1]
        ##动态部分获取
        #浏览器
        headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'}
        s = requests.Session()
        s.headers.update(headers)
        #一般动态
        data0 = {'nid': bookid}
        t1 = s.get("http://book.sfacg.com/ajax/ashx/GetTags.ashx", params=data0)
        Item['Tags'] = t1.json()
        t2 = s.get("http://book.sfacg.com/Ajax/ashx/GetTicketNum.ashx", params=data0)
        Item['MonTicketNum'] = t2.json()
        t3 = s.get("http://book.sfacg.com/Ajax/ashx/GetNovelPointSet.ashx", params=data0)
        Item['point'] = t3.json()
        t4 = s.get("http://book.sfacg.com/NovelData/Statistic/%d.js" % bookid)
        time.sleep(0.15*random.random())
        p1 = int(re.findall(r'viewTimes.*?(\d+)', t4.text)[0])
        p2 = int(re.findall(r'bookMarknum.*?(\d+)', t4.text)[0])
        p3 = int(re.findall(r'favSticks.*?(\d+)', t4.text)[0])
        p4 = int(re.findall(r'pointUserCount.*?(\d+)', t4.text)[0])
        p5 = int(re.findall(r'point.*?(\d+)', t4.text)[0])
        Item['view_time'] = p1
        Item['bookMarknum'] = p2
        Item['favSticks'] = p3
        Item['pointUserCount'] = p4
        Item['sum_point'] = p5
        ##图片
        cover_url = response.xpath("//ul[@class='synopsises_font']/li[1]/img/@src").extract()[0]
        Item['cover'] = self.test_url(cover_url) 
        #背投
        beitou = response.xpath('//head/style/text()').re('(http://rs.sfacg.com/web/novel/images/images/beitou.*?)\\"')        
        if len(beitou) == 0:
            Item['hav_beitou'] = False
        else:
            Item['hav_beitou'] = True
            Item['left_beitou'] = self.test_url(beitou[0])
            Item['right_beitou'] = self.test_url(beitou[1])
        return Item

iqing.in爬虫

iqing_in.py

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

import requests,re, os, time, codecs, random, json
import markdown_make

class down_book(object):
    def __init__(self,url,down_type, sleep=False, update=False):
        #base
        self.in_url = url
        self.sleep = sleep
        self.time = time.ctime()
        self.os_name = os.name
        if down_type == 'l':    #web(w) or local(l)
            self.down_type = True
        else:
            self.down_type = False
        #base2
        self.cover_url = ''
        self.c_ids = []
        self.i = 0
        self.img_dir = ''
        self.txt_dir = ''
        self.c_start = []
        self.book_url = ''
        self.json1 = dict()
        self.json2 = dict()
        self.json3 = set()
        #extends
        if re.search('book',self.in_url):
            book_id = re.findall('(\d+)',url)[0]
            self.index(book_id)
            self.c_start = self.down_web(self.c_ids[0])
        elif re.search('read',self.in_url):
            c_id = re.findall('(\d+)',url)[0]
            self.c_start = self.down_web(c_id)
            book_id = self.c_start[3]
            self.index(book_id)
        else:
            print('the url error')
        path_now = os.path.abspath('.')
        if self.down_type:
            dir_name = self.c_start[3] +'_' +self.c_start[2] +'_' +self.c_start[4] +'_l'
        else:
            dir_name = self.c_start[3] +'_' +self.c_start[2] +'_' +self.c_start[4] +'_w'
        self.s_dir = os.path.join(path_now,dir_name)
        if not os.path.exists(self.s_dir):
            os.mkdir(self.s_dir)
        self.txt_dir = os.path.join(self.s_dir, 'md')
        #json
        json_path = os.path.join(self.s_dir,'json.json')
        if os.path.exists(json_path):
            with codecs.open(json_path,'r','utf-8') as j:
                json_s = j.read()
            json_in = json.loads(json_s)
            self.json1 = json_in[0]
            self.json2 = json_in[1]
            self.json3 = set(json_in[2])
            if update:
                self.json3.clear()               
        #down
        print('\n下载开始……')
        print(self.s_dir)
        print(self.c_ids)
        print(self.book_url)
        if self.down_type:
            self.down_img(self.cover_url,'cover')
        for c_id in self.c_ids:
            if not self.json3.__contains__(c_id):
                self.down_web(c_id)
                if self.sleep:
                    sleep_time = 0.05+random.random()*0.1
                    time.sleep(sleep_time)
        #log
        self.log()

    def index(self,book_id):
        in_url = 'http://www.iqing.in/book/%s/' % book_id
        self.book_url = in_url
        index = requests.get(in_url)
        i_c = index.text
        cover_urls = re.findall(r'src="(https://image.iqing.in/cover/.+?)\?imageView|src="(https://image.iqing.in/submit/image/.+?)\?imageView',i_c)[0]
        for cover_url in cover_urls:
            if cover_url != '':
                c_ids = re.findall(r'href="/read/(\d+)"',i_c)
                c_ids.pop(0)
                self.c_ids = c_ids
                i = 1
                for t in self.c_ids:
                    self.json1[i] = t
                    i = i + 1
                self.cover_url = cover_url
                return

    def down_img(self,url,append=''):
        self.img_dir = os.path.join(self.s_dir,'img')
        print(url)
        if not os.path.exists(self.img_dir):
            os.mkdir(self.img_dir)
        if append == '':
            img_name = os.path.split(url)[1]
        else:
            img_name = '!' +append +'_' +os.path.split(url)[1]
        img_path = os.path.join(self.img_dir,img_name)
        if (not os.path.exists(img_path)) and append != 'n':
            i_r = requests.get(url, stream=True)
            i_r_c = i_r.content
            with open(img_path, 'wb') as i_f:
                i_f.write(i_r_c)
        return img_name

    def down_web(self,c_id):
        print(c_id)
        c_url = 'http://www.iqing.in/content/' +c_id +'/chapter/'
        r = requests.get(c_url).json()
        volume_title = r[u'volume_title']
        chapter_title = r[u'chapter_title']
        book_title = r[u'book_title']
        book_id = str(r[u'book_id'])
        # next_chapter_id = r[u'next_chapter_id']
        author_name = r[u'author_name']
        updated_time = r[u'updated_time']
        self.json2[c_id] = {'volume_title':volume_title,'chapter_title':chapter_title,'updated_time':updated_time}
        t = [volume_title,chapter_title,book_title,book_id,author_name,updated_time,c_id]
        if self.i != 0:
            self.text_write(r,t)
            self.json3.add(c_id)
        self.i = self.i + 1
        return t

    def text_write(self,r,t):
        self.txt_dir = os.path.join(self.s_dir, 'md')
        if not os.path.exists(self.txt_dir):
            os.mkdir(self.txt_dir)
        # file_name_r = str(self.i) +'_' +t[0] +'_' +t[6] +'_' +t[1] +'.txt'
        # if self.os_name == 'nt':
        #     file_name = re.sub(r'\\|\/|\:|\*|\?|\"|\<|\>|\|', '_', file_name_r)
        # else:
        #     file_name = re.sub(r'\/', '_', file_name_r)
        file_name = t[6] +'.md'
        txt_path = os.path.join(self.txt_dir, file_name)
        updated_time = '*' +re.sub('T',' ',t[-2]) +'*'
        # f = codecs.open(txt_path,'w','utf-8')
        with codecs.open(txt_path,'w','utf-8') as f:
            c = '##%s\n\n**%s**\n\n%s\n\n---\n\n' % (t[1],t[0],updated_time)
            f.write(c)
            for c_r in r[u'results']:
                #文字
                if c_r[u'type'] == 0:
                    r_c = c_r[u'value'] +'\n'
                    c = re.sub('\n', '\n\n', r_c)
                    f.write(c)
                elif c_r[u'type'] == 1:
                    img_url = c_r[u'value']
                    if self.down_type:
                        img_name = self.down_img(img_url)
                        c = '![%s](img/%s)' % (img_name, img_name) +'\n\n'
                        f.write(c)
                    else:
                        img_name = self.down_img(img_url,'n')
                        c = '![%s](%s)' % (img_name,img_url) +'\n\n'
                        f.write(c)
            f.close()

    def log(self):
        end_path = os.path.join(self.txt_dir,'9999.md')
        with codecs.open(end_path, 'w', 'utf-8') as end:
            i_end_c = '##Book Infomations\n\n---\n\n**BookName:** [%s](%s)\n\n**BookId:** %s\n\n**BookAuthor:** %s\n\n**DownTime:** %s' % (self.c_start[2],self.book_url,self.c_start[3],self.c_start[4],self.time)
            end.write(i_end_c)
        if self.json1.get('9999', True) == True:
            self.json1[9999]='9999'
            self.json2['9999']={'volume_title':'END', 'chapter_title':'Book Infomations'}
        #json
        json_path = os.path.join(self.s_dir,'json.json')
        json3 = list(self.json3)
        with codecs.open(json_path,'w','utf-8') as j:
            json_out = [self.json1,self.json2,json3]
            json_s = json.dumps(json_out)
            j.write(json_s)
        #xhtml
        markdown_make.mark2html(self.s_dir)
        #final log
        with codecs.open('iqing.in_history.log' , 'a', 'utf-8') as f:
            history = '%s,%s,%s,%s,%s,%s\n' % (self.time, self.c_start[2], self.in_url,self.c_start[3],self.c_start[4], self.down_type)
            f.write(history)

if __name__=='__main__':
    url = input('plese input url: ')
    down_type = input('plese input download type(web(w) or local(l)): ')
    update_in = input('update(t:True,f:False)')
    if update_in == 't':
        update = True
    else:
        update = False
    Iqing = down_book(url,down_type, update=update)

markdown_make.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import markdown,codecs,os,re,json, shutil

class mark2html(object):
    def __init__(self,folder):
        #根目录
        self.folder_r = folder
        print('开始转换……')
        print(folder)
        #源
        self.folder_s = os.path.join(self.folder_r, 'md')
        #结果
        self.folder = os.path.join(folder, 'xhtml')
        #delete dir
        if os.path.exists(self.folder):
            shutil.rmtree(self.folder, True)
            print('%s removed!' % self.folder)
        #mkdir
        if not os.path.exists(self.folder):
            os.mkdir(self.folder)
        #json
        json_path = os.path.join(self.folder_r,'json.json')
        if os.path.exists(json_path):
            with codecs.open(json_path,'r','utf-8') as j:
                json_s = j.read()
            json_in = json.loads(json_s)
            self.json1 = json_in[0]
            self.json2 = json_in[1]
            self.i_n = dict()
            for ts_0 in self.json1:
                self.i_n[int(ts_0)]=self.json1[ts_0]
        #covert
        self.volume = set()
        self.markdown_covert()

    def markdown_covert(self):
        for md_n in self.i_n:
            #md
            md_cid = self.i_n[md_n]
            md_name = md_cid +'.md'
            md_path = os.path.join(self.folder_s, md_name)
            with codecs.open(md_path, 'r', 'utf-8') as f_in:
                md_content = f_in.read()
            #json
            json2 = self.json2[md_cid]
            volume_title = json2['volume_title']
            chapter_title = json2['chapter_title']
            #updated_time = json2['updated_time']
            #volume
            self.volume_file(md_n, volume_title)
            #web
            web_title = volume_title +'-' +chapter_title
            web_title = self.web_title_deal(web_title)
            web_head = '<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>\n<title>%s</title>\n</head>\n<body>\n' % web_title
            web_body = markdown.markdown(md_content)
            web_tail = '</body>\n</html>'
            web = web_head +web_body +web_tail
            #xhtml
            xhtml_name = str(md_n) +'_' +md_cid +'_' +volume_title +'_' +chapter_title +'.xhtml'
            if os.name == 'nt':
                xhtml_name = re.sub(r'\\|\/|\:|\*|\?|\"|\<|\>|\|', '_', xhtml_name)
            else:
                xhtml_name = re.sub(r'\/', '_', xhtml_name)
            xhtml_path = os.path.join(self.folder, xhtml_name)
            with codecs.open(xhtml_path, 'w', 'utf-8') as f_out:
                f_out.write(web)
            print('%s\t%s' % (md_n, md_cid))

    def volume_file(self, cid, volume_title):
        web_title = volume_title
        web_title = self.web_title_deal(web_title)
        web_head = '<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>\n<title>%s</title>\n</head>\n<body>\n' % web_title
        web_body = '<h1 style="text-align: center; ">%s</h1>\n' % volume_title
        web_tail = '</body>\n</html>'
        web = web_head +web_body +web_tail
        #xhtml
        vid = cid -1
        xhtml_name = str(vid)  +'_' +volume_title +'.xhtml'
        if os.name == 'nt':
            xhtml_name = re.sub(r'\\|\/|\:|\*|\?|\"|\<|\>|\|', '_', xhtml_name)
        else:
            xhtml_name = re.sub(r'\/', '_', xhtml_name)
        xhtml_path = os.path.join(self.folder, xhtml_name)
        if not self.volume.__contains__(volume_title):
            self.volume.add(volume_title)
            with codecs.open(xhtml_path, 'w', 'utf-8') as vf_out:
                vf_out.write(web)
            print('volume\t%s' % vid)

    def web_title_deal(self, web_title):
        web_title = re.sub(r'"', '&quot;', web_title)
        web_title = re.sub(r'&', '&amp;', web_title)
        web_title = re.sub(r'<', '&lt;', web_title)
        web_title = re.sub(r'>', '&gt;', web_title)
        return web_title

if __name__=='__main__':
    path = os.path.abspath('.')
    mark2html(path)

无题

- Posted in 贪吃的猫 by with comments

2.png 他先前走着,如果现在回头的话——那人一定也会回头,他强烈地拥有这种想法。没有根据,却充满自信。 于是,在完全走过铁道的时候,他缓缓转过身看向那位女性。她也慢慢转了过来,二人目光交错。 就在心与记忆即将沸腾的瞬间,小田急线的特快列车挡住了二人的视野。

电车通过之后,他想。她应该还在那里吧。

不过都无所谓。如果他就是那个人的话,这已经算是个奇迹了。他想…… 等这列电车开过之后就向前走,他在心里作出决定。 1.png

2016-07-06

- Posted in 贪吃的猫 by with comments

这个月忙着考试,感觉我这个网站好像已经死了!!


PS1: 刚刚发了一下,发现还有一个节点在。 PS2: 之前发布的时候都是用whonix连接tor,估计是受到编程随想的影响。 但是不得不说,速度有一些堪忧呀!当然也没有那么慢,毕竟是自建的ss服务器,主要是开关虚拟机有一点麻烦,而且发布要实好几次才能成功(当时特殊时期,现在基本不会了)。 于是计划不戴tor了,裸身上阵。 如果我这都被XXX了,那我也无话可说了! PS3: 感觉自己的网站好丑,打算优化一下。 计划加上标签。 当然这还不在日程上,毕竟还有其他事情要做。

2015.6.4

- Posted in 贪吃的猫 by with comments

今天答辩终于完了,忙了好一会。

刚刚在论坛里看到有人发有关6.4的纪念帖子。

紀念89學運27週年,為64死難者默哀 向為了民主訴求而犧牲默哀,為了無辜慘遭屠殺的市民默哀!

以前看了6.4的纪录片,确实有一些感想,现在回想起还是有一些感想,但更多的是一些静默,一种漠不关心。 我不知道是什么改变了。 现在我只是默默的看看,翻墙出去瞄瞄,看看都有什么动向,但并没有什么鸟用。

也许政治这种东西是肉食者关心的事,我们屁民就好好待着吧!

PS:中国互联网维护日互联网可用性测试


杭州电信: 无界:找不到服务器 自由门:找不到服务器,使用 DNSCrypt 后可以找到服务器,但是访问不了网页 赛风:正常连接,速度尚可 蓝灯:连接上但不稳定,速度极低常常无法访问,提示连接被重置 某商业 Shadowsocks 服务:连接正常

杭州移动:

无界:正常连接 自由门:正常连接 赛风:无法连接 蓝灯: 正常连接 某商业 Shadowsocks 服务:连接正常 Freenet Opennet:性能明显减低,连接数减少 Tor -meek-amazon:正常连接 Tor -meek-azure:正常连接

看起来移动下挂掉的情况不是很严重,电信还是挺严重的,不过至少还能用。

2015.06.02

- Posted in 贪吃的猫 by with comments

老周曾经说过,忙完秋收忙秋种,学习学习再学习。

但是上了大学以来就没怎么努力学习,绩点也有一点惨不忍睹。 马上6级了,没有复习,八成过不了

六一儿童节快乐

- Posted in 贪吃的猫 by with comments

虽然已经6月2号了

太热了

- Posted in 贪吃的猫 by with comments

刚刚看了下温度计29度,没有空调的夏天真的很难过!

呃。。。。有人担心开启白名单模式了

附: 互联网上你不知道的新疆断网(转贴)

互联网上你不知道的新疆断网(转贴)

大牛编前语:下面这篇文章是新疆断网时一位热心网友写的并且帖在新疆家园天网上,记录了新疆从断网到2009年12月25日期间的互联网历史。在这个中华人民共和国成立61年的大喜日子里,本着历史不能出现断档的原则,我把他转贴出来,作者不详,感谢天网,谢绝本省跨省的一切形式的追捕。


互联网上你不知道的新疆断网

现在新疆全境依然是断网断短信断国际长途三断中。这种中断跟内地的GFW不尽相同,对于普通用户基本上算是物理隔离,几乎所有ip和端口均无法访问。能够访问的只有疆内的站,以及极少数ip和主机在外地的国家级官方网站(如网站备案查询、各种考试报名网站)。也就是说,国内公众网的GFW是默认放行,部分ip和域名拦截+关键词拦截;而新疆是默认断开,个别ip和域名放行。

上网方式方面,7月6日凌晨4点chinanet全部封锁,随后是移动、联通的公众网络。教育网(CERNET)估计是用的电信出口,也是同步被封。科技网(金桥)多撑了两天,于7月9被封锁。手机上网方面,NET方式均同时被封锁,WAP方式则推迟到七月十几左右才封锁,其中电信的WAP方式甚至到了 8月中才封锁完毕,期间一直可以登录WAPQQ。3G上网卡方面,基本是同时封锁,有传闻是如果用天翼3G拨号时获得的IP是120.X.X.X就可以顺利上网,不过这个传闻未验证。普通用户能够翻出GFW终极版的上网方式只有拨号一种了,也就是10年前我们大家常用的56k窄带拨号。具体方式后文详述。

短信方面,点对点短信均无法发送,手机端直接报错,应该是点对点短信网关根本就没启动。仅有部分公众SP业务开通,如天气预报、手机报、 10000/10086/10010这类的运营商官方信息,用户可以接到。需要注意的是外地手机漫游至新疆,一样无法发短信,所以不要妄想买个外地短信卡就能在新疆聊天了。我自己曾经发短信如飞的手指,现在也快不知道怎么按了。可以说这几个月新疆的SP和CP类公司遭到了重创,倒闭关门或撤回内地的不计其数。

国际长途方面,大概是7月7*开始就非常难以拨入,8月以后就基本无法拨入了。呼出方面,除了当局指定的仅有几个机关单位和几个大的电信营业厅可以打(像不像80年代),其他全部的直播、IP、网络国际长途电话均无法呼出。批发国际ip卡的商家亏到出屎,新疆大批做中亚外贸的商家也都难以开展业务。我的表妹在马来西亚上学,快半年了没一个电话,她老妈被逼的请了假去内地上网,终于在QQ上得以一见。

断网后的这些封锁,除国内长途封锁时间较短,断网后几天即解除外,其他的直到现在(12月25)也没有一点儿放松的迹象。基本每个月都有传闻说这个月/下个月要开网,什么时候开网也是疆内各论坛最常讨论的一个话题,已经不能用经来形容了。可惜这些期望,最后都是以失望告终。

断网持续48小时:这是7月6最初的传闻,据说来自于运营商。可惜随着7月7汉族大规模游行警告告吹。

断网一周:参照石首,这个传闻很快告吹。

断网半个月/一个月:说西藏314时断网就这么久,新疆也会参照。可惜据我本人考证,西藏当时似乎没有断网,或断网时间很短。在Google上搜“西藏 断网”,貌似没有什么有价值的信息,希望有了解情况的JR说说。

10月国庆后开网:这个传闻是说都60大寿了,安定和谐的天朝肯定会给我们这2000w*民开网。告吹。

11月1*开部分门户网站,春节放开全部:这个传闻是最有模有样的,据说是自治区级领导安排,大部分运营商都内部通报了。可惜现在马上新年了,仍然没有一个门户网站能够访问。这个传闻应该为真,据说最后是自治区政法委书记符强同志强力压了下来。

最新的传闻是说1月份要开放部分门户,全部放开到2010年5月份左右:这个消息同样来自运营商内部,然则已经没有多少人关心了。对通网的传闻新疆的网民早已麻木,对这类消息都是无奈的一笑了之。

二、翻墙

下面来说说大家最关心的,那些能上网的新疆人,是怎么从铁桶一般的墙里翻出来的。

首先,内地公网使用的翻墙方法完全不适用于新疆,因为封锁的原理不同。新疆现在就是一个大局域网,断网根本就不通,你提供哪些国外的翻墙网站或者翻墙软件,自然只会404 not found或者service unveilabe。现在已知的是如下几种方法:

这个是应用最广泛的拨号方式,你不需要有特权,也不需要上面有人,只要你有一个破旧的56k窄带猫,连上电话线就可以。虽然速度很慢,开个新浪都要等2分钟,但是,那是**啊(请自行脑补加入流泪233表情)!当然,你不能拨本地的窄带接入号,那一样只能访问疆内网。

流行的拨号号码有这些:

022-16300、0891-16300:8月起,这两个号码造福了很多网民。稳定,但不容易拨入,平均拨号5次能够连接上,10月份被封。

010-95700:10月到12月间,这是最流行的拨号接入号,拨通率非常高。如果你看到有人家里固话电话费突然升到好几百元甚至上千元,那不用问,肯定是天天95700呢。这个号码12月初被封。

0756-96169:95700不在的日子,我们又找到了96169。可惜没能坚持1个月就被封了。

友情提醒:拨长途窄带ISP号码前请加拨11808,这样一小时话费能够控制在5元以内,否则请按长途标准资费(大约1分钟7毛钱)换算自己的电话费。

2、企业内网:

大家知道很多大型企业的内部网络都是全国连通的,电信运营商自不必说,其他包括铁路、石油、银行等都有自己的全国性网络,由于各企业的业务需要,这些内网是不可能断掉的。这就给通过内网翻墙带来了可能性。只要在其他省份找到一台同在内网且可以上网的机器,于其上开个代理,便可以顺利上网。一时间,“内地同事 ”成了抢手货,疆内软件网站上ccproxy、wingate这些代理软件也都上升到下载榜前列。

这种翻墙方式网速尚可,实现难度也不算太高,也算是比较流行的翻墙方式。当局下强硬命令要求各单位逐机清理的7-5视频,大多也是这种方式流传出去的。

3、海事卫星等卫星通讯方式:

卫星通讯方式的特性决定了它不可能像有线网络一样被地区性中断,有条件的单位和个人,可以通过这种方式翻墙。不过这种方式网速不怎样,而且资费极贵,所以基本只有少数单位在使用。

有次翻墙出来上QQ遇到一个疆内的朋友,问他怎么上网的,便给我炫耀其单位特权申请了卫星专线4条,办公室电脑都能上网了云云。

4、特权

在中国,任何事情的限制范围,都可以加一条:领导例外——就连断网都断得这么有中国特色。除了通讯管理局、公安厅、安全厅这些跟互联网直接有关的单位可以上网外,据我所知还有各通讯运营商处级以上领导,当局机关的部分部门,疆内官方大站的运营部门(亚心网、天脉、亚心网、亚心网、**),均可以顺利上网。当然,各单位都有相应的管制手段,如限制部分端口,限制QQ登录等,但还是让普通百姓羡慕不已。

当然,普通企业和个人“原则上”也可以申请开通,但除非你能通过电信运营商-通讯管理局-公安/安全/自治区当局多个部门层层审批通过才行,至今通过的公司寥寥无几,个人更是不要奢望了。

5、异地上网方式

之所以新疆能被这么彻底的断网,跟新疆的地理位置也有很大关系。如果内地的某个省份出事被断网,网民很容易就能到别的省去,而且内地错综复杂的线路也不是能说断就断的。新疆的骨干网出疆端口只有两条,很容易就能封锁。如果你想出去外省,哪怕是到最近的甘肃,那一千多公里的路程至少也得1整夜的火车。

但即便这样,仍然有难以忍耐的网民跑去外省上网。BBC就报道过一个新疆人坐飞机去深圳上网的事情。而新疆本地QQ上流传的一条信息则是:“柳园一出车站就有好几家网吧,我去过了。网吧对面就是旅馆,下火车出站就可以上网了。那个网吧全是新疆这边的,本地人基本没与几个,到了晚上8点全是新疆的网民。包夜 8 块钱。10点到早上9点。就这些了。过年时候我也要去 我的电话136699xxxxx要去一起呵呵!”——柳园是甘肃省离新疆最近的一个小火车站。

还有一则未经证实的消息,是说有人利用手机基站信号的边界重叠,去新疆东南边的若羌县用青海省的3G信号上网。之所以说未经证实,是因为那里是**人口占90%以上的民族聚居地,就算能3G上网,但小命不一定能保全啊……

以上基本就是新疆境内翻墙的方法,发出来给对网络习以为常的里层JR们看看,新疆人民上个网是多么难。有的人QQ密码忘了,有的人苦心经营的网站废了,连菜地都快半年没收成了……去内地出差回来的同事说:“你知不知道当我输入三达布溜淘宝点康木一回车,看到那熟悉的黄色页面出现时,才真正的体会到了什么叫这一刻我内牛满面……

三、现状

断网前新疆 90%以上的互联网流量都是流向内地的,但现在这个大局域网已然成了私服和山寨网站的乐土。各种网游私服层出不穷;利用亚心网和***搭建的新疆QQ也有N个版本了;山寨开心网不下10个,虽然用的都是同一套源代码连界面配色都一模一样;hao123类的疆内网站导航已知的就有几十个;甚至连百度和 Google都被山寨了(参见附图),虽然做的有够烂……最近最火的,则是一个叫zn11的网站,点击率超级高。这个网站是干什么的呢,说出来外面的各位可能会哑然失笑——就是用teleport把新浪、腾讯、网易等几个大站的首页和2、3级页面离线下载,然后挂到站上。虽然可能几天才更新一次,大量链接点不开,视频也无法收看,但还是有很多人上班第一件事就是打开这个zn11。也许是让自己觉得离真正的互联网近一点吧……

这是一个最好的时代,这是一个最坏的时代。对于私服和山寨网站运营者来说,显然是前者。但对于电信运营商来说,很有可能是后者。虽然广播报纸上电信移动联通三家的3G广告还是铺天盖地,但是谁都会对“WCDMA,上网速度可达7.2兆”的广告一笑了之,网都没了推广什么3G啊。损失最重的是主要收入来自于宽带业务的新疆电信,7月份全疆宽带费用全免,一个月直接损失5000多万,关联损失8000多万。8月份以后宽带费用采用用多少交多少不用不交,最多收取原费用8折的方法,但已然抑制不住每月飙升的宽带拆机量了。

上不了网的不方便,很多人已经渐渐习惯了。官方大站上不少“没有互联网的*子,我过得更好了”这类的傻逼帖子,甚至我朋友里也出现了斯德哥尔摩综合症患者。但我想大家更为担忧的,应该是TG在观察过新疆百姓对三断的反应之后,会不会把这个损招用在其他省份,甚至全国。

呵呵哒

- Posted in 贪吃的猫 by with comments

毕竟西湖**月中,风光不与**时同。

5月35日

- Posted in 贪吃的猫 by with comments

在5月35日来临前夕,让我们用更伟大的墙欢迎它的到来!

greatfirewall.png