美文网首页Python自动化运维python 入门python开发
工具向——用python自动化修改hosts翻墙

工具向——用python自动化修改hosts翻墙

作者: treelake | 来源:发表于2017-08-31 13:54 被阅读2719次

简述

  • 谷歌搜索对于优秀的技术内容的友好性要强于百度,YouTube上也有不少很棒的技术视频(如PyCon)(台湾小妹子也不错,:)),对于自学技术的同学,翻墙可以说是良好的助推器。
  • 翻墙有一个简单的方法,就是修改本机的hosts文件(详见知乎:修改 hosts 文件的原理是什么?),windows下hosts文件一般位于C:/Windows/System32/drivers/etc/目录下。
  • 在github上有一些良好的hosts源提供(欢迎朋友们分享更多可靠源),但是要下载下来并且手动替换hosts文件并刷新dns缓存还是挺麻烦的。用python可以轻松地实现自动化这一过程。
  • 普通用户可下载exe体验,百度云链接:http://pan.baidu.com/s/1eSalgn4 密码:3q2l。需要右键以管理员运行(一般情况尽量不要以管理员运行未知来源的应用程序,不过本程序代码在后文可查,纯净无害)。(此外,可以通过windows服务设置定时任务自动运行该exe)。(谷歌访问请用https,如 https://www.google.com.hk/

概要

  • 跳转到hosts文件所在目录:
    (注意:操作hosts文件需要管理员权限)
import os
path = r'C:/Windows/System32/drivers/etc/'
os.chdir(path)
  • 使用partial函数封装一个带默认请求头的requests.get函数 - p_get
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
}

import requests
from functools import partial
p_get = partial(requests.get, headers=headers)
  • 判断是否能访问谷歌:
if p_get('https://google.com.hk', timeout=2).status_code == 200:
        print('You ALREADY can access Google!')
  • 从hosts源获取hosts文件内容:
url = 'http://.......'
p_get(url).text
  • 读取原有hosts文件内容:
f_content = ''
with open(file, 'r', encoding='utf-8') as f1:
    f_content = f1.read()
  • 写入新内容:
with open(file, 'w', encoding='utf-8') as f1:
    f1.write(new_content)
  • 其他:
    1. 代码中遍历尝试几个备用源,直到可以访问谷歌。都不可以就gg了。
    2. 可以从文件中读取新的自定义源。
    3. 代码中EXTRA_HOSTS内容是因为本人使用老版本potplayer,禁止其自动更新的一种方法是封掉它的更新链接地址,对其它用户一般没有影响,故保留。
    4. 使用pyinstaller Gethosts.py --onefile生成单个可执行文件,在右键属性-兼容性中勾选为以管理员运行,就可以双击打开了。

代码

  • 命名为Gethosts.py
# pyinstaller Gethosts.py --onefile
import os
# import shutil
import time
import datetime
# import win32file

path = r'C:/Windows/System32/drivers/etc/'
os.chdir(path)
file = 'hosts'

backup_urls = [
    'https://raw.githubusercontent.com/wangchunming/2017hosts/master/hosts-ipv6-pc',
    'https://raw.githubusercontent.com/wangchunming/2017hosts/master/hosts-pc',
    'https://raw.githubusercontent.com/racaljk/hosts/master/hosts',
    'https://coding.net/u/scaffrey/p/hosts/git/raw/master/hosts-files/hosts',
]
# url2 = 'https://coding.net/u/scaffrey/p/hosts/git/raw/master/hosts'

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
}

import requests
from functools import partial
p_get = partial(requests.get, headers=headers)

EXTRA_HOSTS = u'127.0.0.1 get.daum.net\n'
REWRITE_FLAG = True

def update_hosts(url):
    global REWRITE_FLAG
    
    # os.access(path, os.W_OK)
    # shutil.copy (file, file + str(datetime.datetime.now().date()))
    # win32file.CopyFile(file, file + '-' + str(datetime.datetime.now().date()), 1)
    f_content = ''
    with open(file, 'r', encoding='utf-8') as f1:
        # global f_content
        f_content = f1.read()

    try:
        new_content = EXTRA_HOSTS + p_get(url).text
        # print(len(new_content))
        
        if new_content != f_content:
        
            if REWRITE_FLAG:  # 是否保留历史
                with open(file + '-' + str(datetime.datetime.now().date()),
                    'w', encoding='utf-8') as f2:
                    f2.write(f_content)
                REWRITE_FLAG = False
                
            with open(file, 'w', encoding='utf-8') as f1:
                f1.write(new_content)
            # import urllib.request
            # urllib.request.urlretrieve(url, file)
            print('hosts 已更改')

        os.popen('ipconfig /flushdns')
        # print(os.popen('ipconfig /flushdns').read())
        
    except:
        print('源连接错误', url)


def read_sources(file='./host_sources.txt'):
    '''
    添加自定义源:
    1. 在该应用程序旁新建文件'host_sources.txt'
    2. 在其中添加如下格式的源(链接, 优先级):
        http://a.com/b, 3
        http://c.com/d, 2
        http://x.com
    3. 策略为: 根据优先级排序, 数字大则权重大, 权重大的优先尝试
    '''
    try:
        with open(file, 'r', encoding='utf-8') as f:
            urls = [[i.strip() for i in line.split(',')] 
                if ',' in line else [line.strip(), 0] # 应对单行无权重情况, 可直接注释
                for line in f.readlines() if line != '\n']
            urls.sort(key=lambda x:int(x[1]), reverse=True)
            return [url for url, _ in urls]
    except:
        return []


def try_every_source_to_update_hosts():
    flag = 0
    urls = read_sources() + backup_urls
    for n, url in enumerate(urls):
        print('正在尝试第%s个源' % (n+1))
        print(url)
        update_hosts(url)
        print('正在尝试连接谷歌, 请稍候...')
        time.sleep(1)
        try:
            r = p_get('https://google.com.hk')
            if r.status_code == 200:
                flag = 1
                break
        except Exception:
            print('连接失败, 尝试下一个可用源')

    return flag

    
print(read_sources.__doc__)
try:
    if p_get('https://google.com.hk', timeout=2).status_code == 200:
        print('You ALREADY can access Google!')
except:
    if try_every_source_to_update_hosts():
        print('You can access Google!')
    else:
        print('Ah, sth went wrong...')
        print('请尝试手动访问:\n'
              'https://laod.cn/hosts/2017-google-hosts.html\n'
              '寻找解决方法')


if input('Enter键退出'):
    test_sites = [
        'https://www.google.com.hk',
        'https://www.youtube.com/',
        'https://www.facebook.com/',
        'https://www.tumblr.com/',
        'https://www.twitter.com/',
    ]

    for url in test_sites:
        try:
            r = p_get(url)
            if r.status_code == 200:
                print('success', url, ' ( 耗时: %s)' % r.elapsed)
        except:
            print('error', url)
    input('Enter键退出')

相关文章

网友评论

  • wonwon:链接取消了 谢谢楼主
  • e9215c17de89:楼主还有百度云链接嘛?
  • 遗失的尘埃:学习了😬
  • anxiaozhu:修改hosts不是很稳定,为什么不用ss呢?
    anxiaozhu:@彪飙 要想稳定使用VPS,建议自己购买国外的VPS,并在上面架设SS的服务端。具体的可以google关键词“VPS + SS”,教程很多。稳定且简单。
    苟且偏安: @anxiaozhu 有没有ss教程推荐?
  • 3b1cb819a574:管家说是木马文件?
    treelake:因为程序修改hosts,有可能被当做恶意程序,不过这个暂时可以放心使用
  • Fantasy丶7:不不不,我们不翻墙,只是科学上网\(*ΦωΦ)ノ
  • 現實世界:这个不是App?
    treelake:@現實世界 PC就是个人电脑,程式是文中的exe吧
    現實世界: @treelake PC是程式吗?
    treelake:不是,只适用于PC,可尝试使用kivy转化为app供手机使用

本文标题:工具向——用python自动化修改hosts翻墙

本文链接:https://www.haomeiwen.com/subject/aslqjxtx.html