0%

跑代码的时候迷迷糊糊睡着了,梦到在跟三岛喝茶聊天,茶水太烫就醒了,到底聊了什么也记不真切了,倒是提醒我在记忆没模糊之前赶紧记下些东西。

我是在2018年初去的日本,掐头去尾总共待了六天,走了大阪、京都和东京这三个城市,赶在东京大雪前一天回的家。当时对日本文学特别痴迷,无法拒绝留白带来的情感上的刺激,于是很坚定地决定一个人旅行。

在关西国际机场下了飞机,搭乘关西机场线前往市区。原本打算乘南海电气铁道特快的,就是那个蓝色的铁胆火车侠,结果发现忘买特快票了,只好搭乘慢车,就当慢慢欣赏沿途风景了。从乡间驶向城郊,最后进到市区,原本车上大多都是来旅游的小家庭,慢慢多了些提着公文包下班回家的人,再后来是穿着制服的学生,从上车到下车一直喋喋不休,感觉和旁边安静看书的上班族像是两个世界的人。我总觉得有些格格不入,内心是活泼的,行为又受诸多克制,像夹在两者中间,后来索性从座位站了起来专心看窗外。日本这些JR线路车票都挺有意思的,仔细看上面印着些动漫人物的图案,纸张手感也不错,我特意随身带了一个收藏夹,把车票、门票还有小票这些乱七八糟的小玩意儿都收了起来,现在应该还躺在家里的书橱里。

到酒店放好行李,听懂了“black fast”是什么意思之后,就直接跑去梅田蓝天大厦,想看看日落,结果忘了有一个小时的时差,出了地铁站已经天黑了,直接成了看夜景。展望台真的是像星空一般洒了点点荧光,城市的灯光看得入神。下了楼差不多也有七八点了,刚好跑去道顿堀吃晚饭。记得很清楚第一顿吃的是金龙拉面。日本点菜是有一个小机器,每道菜有个按钮,想吃什么就按什么,然后直接在机器上付钱拿小票,再把小票给店家就好了。我偷偷看前面几位的操作,就学会了,避免了尴尬。金龙拉面的店面是半露天的,有点像武侠小说客栈的那种感觉,体验很棒。之后在道顿堀心斋桥边走边看,尝了街边的章鱼丸子,还有另几样叫不出名字的小吃,吃饱喝足后回家。

第二天一大早去了大阪城公园和里头的天守阁。公园其实没什么可看的,跟普通城市公园没什么两样,大多都是老人在晨练健身。天守阁前养了不少鸽子,有一些家长带着孩子在那儿玩儿。可能因为比较早,那个时间段就只有我一个人乘电梯上天守阁,电梯管理员看我好像不是本地人就突然用中文问好,挺惊喜的,跟我说她正在学一点中文,听着没什么口音。天守阁上也就是讲一些日本战国历史,并没有什么特别新奇的,随便转了一会儿就下来了,找到了一个卖冷饮的车,买了一个抹茶甜筒吃。

这次旅行并没有做太详细的攻略和准备,只是粗略地在纸上写了一些地点,然后看时间和心情走到哪儿是哪儿。下午乘车到了四天王寺附近,吃了顿连锁猪排饭,不知道是不是因为走了一早上太饿了,出奇的好吃。四天王寺那段时间好像刚好在修缮,有一部分建筑被帷幕遮着,也有一些脚手架。寺院人不是很多,大部分是老太太,会花一点钱点一根蜡烛,经过的时候会点头示意,觉得是有一些仪式感在那里的。从四天王寺出来,好像经过了一所幼稚园,误打误撞到了一个叫极乐净土之庭的地方,我看时间还早就进去走了走,没成想竟到了个小世外桃源。园中景观布置很精致,有一些中式园林的感觉,有些岔出的小径尽头会摆上神龛,好像有说法会摆上心脏做祭品,西部世界也有过相似的场景。那天只有我一个游客,真的有种极乐净土的感觉。晚上跑去法善寺横町吃了晚饭,是一家吃串串的店,门口有个大玩偶的,名字记不住了,旁边还有一家买红豆粥(?)的。整个法善寺横町的灯光和氛围特别有日式传统的感觉,刚好下过一点小雨,吃完饭在附近散了散步,有烟火气。

在大阪的最后一天踩了踩马路,逛了逛通天阁新世界,傍晚去了港口,第一次乘了摩天轮。回家的路上余晖洒在新刷完字的柏油路上,拓下了房屋和电线杆的影子,一瞬间有所感。好像还有一些去过的地方,像是难波、御堂筋、黑门市场,已经记不太清了。

第二站京都,一座很美好的城市,我一直有些后悔没有留足够的时间游览。从大阪到京都乘的JR电车,很快就到了,在车站寄存了行李之后就直接乘公交去了清水寺。在日本的这几天好像天气都很遂我愿,恰好下着小雨,和清水寺很般配。虽说不是红叶季,古朴的建筑依然很有美感。穿过回廊,走过大殿,一直想着“音羽山清水寺”的名字,觉得实在是太美了,雨打芭蕉,好像听到了石琴的乐音,“松風與音羽瀑布之清水,教鬱結的心涼爽暢意”。据说清水寺是祈愿爱情的地方,于是我也求了一福袋赠予她。从清水寺出来雨也渐渐停了,天空染了晚霞的色彩,沿着三年坂、二年坂的街道下山,两旁有卖抹茶和手工艺品的作坊店铺,也有门口用帘子遮着的居酒屋。我很喜欢听路人谈笑聊天的声音,即便不明白他们在说些什么,但那么开心一定是很有趣的事情。回住处之前先去车站取寄存的行李。一开始我并不知道原来日本同站进出哪怕不乘电车也是要买票的,稀里糊涂地进了站,拿了行李却发现出不了闸机,于是一脸茫然的问服务站的姐姐,讲解一番之后替我开了门,也没有让我补票。我有些记不得京都的第一晚去了哪里,好像只是在住处周边散了散步,那一片都是两三层楼的小房子,很安静,反而有了些生活气息。

第二天起了个大早,赶着乘车去伏见稻荷大社。因为要换乘两三条线路,在车站拿了张地图,用笔圈画出了换乘站,一路参考路牌和指示,竟有一种小学生第一次出远门的兴奋感。大概七点刚出头就到了神社,虽然离标注的参拜时间还有半个小时,但其实已经允许游客上山了,于是乎一个人独享了千本鸟居,如照片中的一般漂亮,尤其是有阳光斑驳穿过缝隙的时候,是能让人心静的地方。千本鸟居朝上就很少有游客会去了,石阶两旁立着石碑和神龛,供奉着很多神祇。有两处平台可以请护符,我看到一个木质的白狐守,很喜欢它的造像,就带了一个放在背包里,后来在安娜堡的时候有一次差点儿被车撞,回到家发现它从中间整整齐齐断成两截,有那么一丝恍惚。爬到山顶还是需要一些体力的,从那里的观景台可以俯瞰京都,还有卖抹茶冰淇淋的地方,我抵制不了这样的诱惑。下山的路上游客变得越来越多,千本鸟居更是挤满了人,全然失却了美感。我记得那天刚好还是一个祭祀日,说是在下午会焚烧木签祈福,我小小纠结了一番,还是决定去下一个目的地,在我的小本子上还记着太多想去看的地方。

出了神社就直奔车站乘电车去金阁寺,顺带在路边花了五百日元买了一串烤肉当午饭,分量很足吃的很香。最开始接触日本文学是在高中,受同桌的影响开始看一些日本作家的书,记得有天他买了川端康成的《古都》、《千只鹤》和《睡美人》放在寝室,打算作为生日礼物送给某个女生,书的封面很漂亮。《金阁寺》也是最早听说的日本文学之一,虽然到现在都没能认真读完,印象里书中的金阁寺在一座小山上,能看见海,应该是我记错了。在金阁寺看到一个拿着哈苏相机的老人,很认真地在拍庭院的景观,在一群等着阳光和金灿灿的金阁寺合影的游客里显得很特别。离开金阁寺恰好是放学时间,街道上是三五成群嬉戏玩闹的小学生,我也跟着一路走去车站打算乘车回市区。

一路天空开始下起了小雨,云层舒卷,给京都添了些厚重感。在鸭川河畔下了车,雨也渐渐停了,于是乎沿着鸭川散步。鸭川的水很清,也很浅,能听到汩汩的水声。沿河散步的多是伴侣,有年轻人也有老人,牵着手,说着悄悄话。水中有云的倒影,我很享受这般宁静平和的氛围。之后又走了走河畔的小巷弄,积水的石板路映着红灯笼,朦朦胧胧中又转去了花间小道。我曾听说会有艺伎穿行于祇园和花间小道,可惜并未得见,小道上的酒家店面都挂着门帘,望进去是道道屏风,有着身穿和服的女子和举杯的客人。我徘徊了许久,想象着樱花盛开,粉白与红。

京都休息得很早,八点不到店家都关门了,道路旁只有卖唱的歌手抱着吉他弹着情歌,吉他包里摆了他专辑的小样,散着路人的赞助。我闲来无事,又走去八坂神社看看。果然夜晚的神社更有氛围,红灯笼都亮着,显得鸟居和神庙更具宗教的庄严。我本以为我是唯一的访客,却在灯火阑珊处遇到身穿红色和服祈愿的女生,怔怔得停下脚步只可远观,不远处的水舍旁躺着睡觉的小猫,神性就在那一瞬间。后来在安娜堡的落雪天,我看完了夏目友人账,每每看到神社和猫咪老师就会想起那天在八坂神社躺在手水舍旁睡觉的小猫和穿着红色和服祈愿的女生。

京都还有许多可讲的故事,可惜记忆有些模糊了。二条城的庭院建筑,夜晚一个人的公交车,还有祇园什俐的抹茶,留待日后再去重温了。

日本行的最后一站是东京。从京都乘坐新干线去东京,在站台迷失了方向,又被列车员误导上错了列车,好在开车前意识到了问题,才不至于耽误行程。到了东京第一件事就是去罗森预约三鹰之森吉卜力美术馆的门票,很遗憾在东京的两天都已预约满了,于是只能买个饭团外加一瓶牛奶安慰一下自己,口味和国内略有不同,牛奶更浓一些。东京的住处在新宿站旁,交通很便利,房间小而精致,从窗户望去能看到新宿站。放好行李我直接就去了歌舞伎町,看看传闻中的灯红酒绿。夜晚歌舞伎町确实是最繁华的地段,霓虹灯闪得刺眼,街上也都是穿着艳丽的女郎还有分发传单邀请客人的风俗店员工。短短十分钟就有三个人上前询问邀请,甚至其中还有和我说中文的。街边也如传言中所说停了不少轿车,车顶都摆了不同品牌的饮料,也有见到女生上前拿起饮料上车扬长而去的,随处可见大城市夜晚的放纵。我来之前算是作了些功课,这些都算是预期之内的故事,让我感到震撼的其实是从歌舞伎町回住处的所见事物。我特意挑了条小路回住处,离歌舞伎町一个街区就是完全不同的世界,没有霓虹灯,甚至路灯都很昏暗,街边有醉酒呕吐的女生,高跟鞋踢在一边,坐在路牙上抱头痛哭,男伴也是衣着零乱不堪,无可奈何地站在一边。商场早已关门了,玻璃门前多了许多纸箱子,走近看里头都是流浪汉裹着衣服在睡觉,想蹭一点商场暖气。如果说歌舞伎町是合法的风流,那附近的小巷子就是真实的情色。昏暗的小巷子里亮着两三盏粉色的灯牌,门窗紧闭,只有二楼的窗户透出一丝亮光。我一直觉得只有在夜晚,城市才会显露出它真实的性格,和光鲜靓丽背后的晦涩无奈。

在东京的第二天上午在城市游荡,下午去了秋叶原。我对日本动漫并不了解,所以也只是去那儿感受一下氛围。满街的海报和不同的动漫人物确实震撼,但好像并没有看到狂热的动漫迷,反倒是日本共产党的宣传车在那儿一刻不停地放着广播。我还去了附近的电器城,早在好多年前国内这样的电器专卖商场就不太多见了。原想着能不能淘到品相不错的胶片相机的,被告知在银座的中古相机店才能找到,后来把竟忘记了这件事,在银座转圈的时候没能记得去看看。晚饭吃的是一兰拉面,一人一个小隔板,在纸上勾选味道和添头就算是点好了,不久就是热气腾腾的一碗面从面前的小窗口递出来,每个客人都在自己的小空间里享受晚餐,好像这种孤独感早已成为了习惯。吃晚饭去了东京铁塔,我没有登塔,只是在附近的一个天桥上远远地看,看了很久,没有什么行人经过天桥,渐渐感到有些难受,后来在某个动漫里看到同样的地点相似的场景,会想起那天的感受。离开东京铁塔已经不早了,但并不想就此结束这次旅行,于是打开地图寻找任何可能的去处,发现在六本木大厦的森艺术中心画廊离停止售票还有二十分钟,于是一路狂奔,还好最后赶上了。看到了一些曾在别处看到的现代艺术,还有一个游戏特展。在回住处的路上经过了一家街边的小饭店,点了一份当地人爱吃的海鲜饭,没有一点儿调味料,原汁原味的海鲜。第三天上午从羽田机场回家。

前段时间听《plastic love》有点上头,想起去年暑假困在安娜堡的时候刘玮伦和他们的乐队翻弹翻唱这首歌,还有半夜开车去中校拍“大城市夜景”的事,会心一笑。

今早电台随机到了Sufjan Stevens的专辑Greetings From Michigan The Great Lake State,看封面图片有些眼熟,下午码代码的时候突然想起来是在西雅图住的工作室里见到过它的黑胶唱片。算是一个小惊喜,又有点萌生买黑胶唱片机的念头。

Apache Nutch and Apache Solr are projects from Apache Lucene search engine. Nutch is an open source crawler which provides the Java library for crawling, indexing and database storage. Solr is an open source search platform which provides full-text search and integration with Nutch. The following contents are steps of setting up Nutch and Solr for crawling and searching.

Environment Setup

Operating System

Ubuntu 20.04.1 64bit running on VMware with 4 cores and 8GB memory

Java

Java Runtime/Development Environment is JDK 1.8/Java 8
Installed by command line

1
sudo apt-get install openjdk-8-jdk

Installation can be checked by

1
java -version

and the result in command line should be

1
2
3
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-8u275-b01-0ubuntu1~20.04-b01)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)

After installation, add the JAVA_HOME parameter to the environment

1
2
vim ~/.bashrc
export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")

If successful, the result should be like

1
2
echo $JAVA_HOME
/usr/lib/jvm/java-8-openjdk-amd64/jre/

Localhost

Check the localhost file

1
vim /etc/hosts

and there should be a line for local ip address similar to

1
127.0.0.1   localhost

Nutch Installation

Download a binary package of Apache Nutch version 1.15 from Apache Archives (https://archive.apache.org/dist/nutch/1.15/)\
Unzip the package and get the folder apache-nutch-1.15/
To verify the installation, run command line

1
2
cd apache-nutch-1.15/
bin/nutch

the result should be similar to

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nutch 1.15
Usage: nutch COMMAND
where COMMAND is one of:
readdb read / dump crawl db
mergedb merge crawldb-s, with optional filtering
readlinkdb read / dump link db
inject inject new urls into the database
generate generate new segments to fetch from crawl db
freegen generate new segments to fetch from text files
fetch fetch a segment's pages
parse parse a segment's pages
readseg read / dump segment data
mergesegs merge several segments, with optional filtering and slicing
updatedb update crawl db from segments after fetching
invertlinks create a linkdb from parsed segments
mergelinkdb merge linkdb-s, with optional filtering
index run the plugin-based indexer on parsed segments and linkdb
...

Solr Setup

Download

Download a binary package of Apache Solr version 7.3.1 from Apache Archives (https://archive.apache.org/dist/lucene/solr/7.3.1/)\
Unzip the package and get the folder solr-7.3.1/
Download corresponding Nutch schema from https://raw.githubusercontent.com/apache/nutch/master/src/plugin/indexer-solr/schema.xml

Set Solr Core

Create resources for a new Solr core nutch

1
2
cd solr-7.3.1/
mkdir -p server/solr/configsets/nutch/

Copy the downloaded schema to core nutch configuration (instead of the schema directly from downloaded Nutch package, otherwise occurs fieldType “pdates” error)

1
cp ../../Downloads/schema.xml server/solr/configsets/nutch/conf/

Delete the schema template

1
rm server/solr/configsets/nutch/conf/managed-schema

Start Solr server

1
bin/solr start

Create Solr core nutch

1
bin/solr create -c nutch -d server/solr/configsets/nutch/conf/

Test the server by launching http://localhost:8983/solr/#/\
Stop Solr server (after the crawling and searching)

1
bin/solr stop

Nutch Integration

The index writer configuration file for Nutch version 1.15 is conf/index-writers.xml in which the format and meta data can be modified

Crawl Setup

Crawl Property

Default crawl properties is set in conf/nutch-default.xml which defines properties for file, http, plugin and so on
Custom crawl properties can be set in conf/nutch-site.xml and there are two must-have properties to set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

<!-- HTTP properties -->

<property>
<name>http.agent.name</name>
<value>Nutch</value>
</property>

<!-- plugin properties -->

<property>
<name>plugin.includes</name>
<value>protocol-http|urlfilter-(regex|validator)|parse-(html|tika)|index-(basic|anchor)|indexer-solr|scoring-opic|urlnormalizer-(pass|regex|basic)</value>
</property>

</configuration>

The indexer-solr is a must in plugin.includes property which is the default setting in conf/nutch-default.xml

Seed URLs

Create a URL seed list file by

1
2
3
4
cd apache-nutch-1.15/
mkdir -p urls
cd urls
touch seed.txt

One URL per line for each site to crawl and it is important to design the seed list to avoid unnecessary pages and reduce crawling time
For example, if the crawling target is the list of professors and students major in computer science, the seed list can be chosen from faculty and student pages of universities

1
2
3
4
https://www.cc.gatech.edu/people/faculty
https://www.cc.gatech.edu/people/phd
https://cse.engin.umich.edu/people/faculty/
https://cse.engin.umich.edu/people/phd-students/

Regular Expression Filters can be configured in conf/regex-urlfilter.txt to limit the crawling range

Crawling

Crawl Database

Databases are used in crawling to store fetched information and the URL queue
Crawl database (crawldb) is provided by Nutch to store URL information obtained by Nutch (seeded or fetched) including the status and the time fetched
Link database (linkdb) is provided by Nutch to store the links to each URL including the source URL and the anchor text of each link
External databases can also be integrated to Nutch but need to configure
Before fetching URLs, insert the seed list to initiate crawldb

1
bin/nutch inject crawl/crawldb urls

Fetching

First generate a fetch list (URL queue) from the database

1
bin/nutch generate crawl/crawldb crawl/segments

The list will be placed in a newly created segment directory names by the timestamp when it is created
Create the abbreviation of the most recent fetch list to make the later expression simple

1
2
s1=`ls -d crawl/segments/2* | tail -1`
echo $s1

Run the fetcher on the segment

1
bin/nutch fetch $s1

The fetching time will depend on the length of the URL list and the number of links in each URL
Parse the entries after fetching

1
bin/nutch parse $s1

Update the database with the results of the fetch

1
bin/nutch updatedb crawl/crawldb $s1

After the first round fetching, the database contains both the initial pages and the newly discovered pages linked to the seed URLs so that a second round fetching can be further processed
Number of top-scoring pages can be chosen when generating the fetching list by the flag -topN

1
bin/nutch generate crawl/crawldb crawl/segments -topN 1000

Indexing

Invert all of the links

1
bin/nutch invertlinks crawl/linkdb -dir crawl/segments

Index all the resources by Solr (use index instead of solrindex which is deprecated)

1
bin/nutch index crawl/crawldb/ -linkdb crawl/linkdb/ -dir crawl/segments -filter -normalize -deleteGone

There are more options for the index command but may not be applied

1
Usage: Indexer (<crawldb> | -nocrawldb) (<segment> ... | -dir <segments>) [general options]

Usually deleting duplication is necessary when indexing, but Solr will handle it automatically

1
Usage: bin/nutch dedup <crawldb> [-group <none|host|domain>] [-compareOrder <score>,<fetchTime>,<httpsOverHttp>,<urlLength>]

After done searching, clean Solr to maintain a healthier quality of index

1
bin/nutch clean crawl/crawldb/

Script

Crawl script is provide by Nutch to allow more options and parameter modification for crawling, but it may not be so useful in crawling a small number of URLs when step-by-step operation and monitor are necessary

1
2
3
4
5
6
7
8
9
Usage: crawl [options] <crawl_dir> <num_rounds>

Arguments:
<crawl_dir> Directory where the crawl/host/link/segments dirs are saved
<num_rounds> The number of rounds to run this crawl for

Options:
-i|--index Indexes crawl results into a configured indexer
...

Searching

After crawling and indexing, launch Solr quey console (http://localhost:8983/solr/#/nutch/query)\
Text queries in the q block using key-value pairs, for example, search pages with key word “system” in “content”

1
content:system


Searching range and other query parameters can be set with provided options

Reference

“阿收则是出神地忆起,实习演员公演时第一场戏的夜晚。他扮演饭店的门童,而且是开幕时就出场的演员,因此帷幕从他的脚边徐徐上升。对于自己以这身装扮,出现在光雾弥漫的观众前,不禁战栗了起来,觉得自己的存在被别人的眼睛吸走了,转移成别人的存在。他忆起了这份战栗……”

“至于镜子,她很喜欢放养这些年轻人,因此也很喜欢他们发呆恍神的样子。她直觉地知道,他们并非在想昨晚的女人。镜子也感受到,旅途将尽、疲惫至极反而复苏的兴奋情绪。唯一烦恼的是,强劲的海风是否会吹乱她的头发……”

心血来潮在阳台拍了一段日落时分的延时,一些参数忘记手动设了,所以噪点好像多了一些,不过把照片做成视频最后的效果看起来还挺不错的。收三脚架的时候不小心摔了相机,有点心疼,还好有兔笼和遮光罩承受一下,机身和镜头都没什么大问题。

得知EVA新剧场版最终章订档的消息非常兴奋,趁着假期又重新看了一遍,甚至头一回找了漫画书,很难想象是什么样的疯子才能画出这样的作品。有点想仔细读一些关于宗教的书籍,说不定会有特别的收获。

Chatbot API Detail

HTML API Request

1
2
3
4
5
6
7
8
function reqListener () {
console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://api.qingyunke.com/api.php?key=free&appid=0&msg=msg");
oReq.send();

Problem

  • [Warning] [blocked] The page was not allowed to run insecure content from http://api.qingyunke.com/api.php?key=free&appid=0&msg=msg
  • Origin null is not allowed by Access-Control-Allow-Origin
  • Both of the above two problems are due to Apple’s policy: Safari does not allow users to disable the block on mixed content

Solution

  • Upgrade HTTP connection to HTTPS connection
  • Proxy the content through an HTTPS connection

最近在卧室新添置了一个小夜灯,也是个小加湿器,造型很简洁,圆底磨砂器皿用来盛水,再加上一个薄薄的白色盖子,感觉有点无印良品的设计。夜晚从水里柔出的光看着格外舒服。我就把它放在床边,睡前就着看会儿书助眠,很安心,慢慢开始理解苦沙弥的习惯了。

疫情对生活的影响还在持续着,虽然出门散步和跑步的次数慢慢增加了,但多多少少还是会觉得有些无聊,于是买了一把吉他,胡乱弹一弹。怎么说呢,手指头要么不够长按不到品格,要么一直打架找不到对的弦,不过渐渐也开始适应了,而且有一个好处,吉他弹出来的音再怎么糟糕都不至于难听,所以也就不用太担心扰民,可以放心大胆地尝试。

再让自己放松恢复一段时间,希望能多些聊天讲话的机会。