工具向——用python自动化修改hosts翻墙
2017-08-31 本文已影响2719人
treelake
简述
- 谷歌搜索对于优秀的技术内容的友好性要强于百度,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)
- 其他:
- 代码中遍历尝试几个备用源,直到可以访问谷歌。都不可以就gg了。
- 可以从文件中读取新的自定义源。
- 代码中
EXTRA_HOSTS
内容是因为本人使用老版本potplayer,禁止其自动更新的一种方法是封掉它的更新链接地址,对其它用户一般没有影响,故保留。 - 使用
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键退出')