diff --git "a/Day66-75/66.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md" "b/Day66-75/66.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md"
index 103c6faf1f795c6934b8df908855dbcabb69556e..16aa85ac3c03396dbef428472f0712b7b843a0e8 100644
--- "a/Day66-75/66.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md"
+++ "b/Day66-75/66.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md"
@@ -115,7 +115,11 @@ HTTP响应(响应行+响应头+空行+消息体):
3. HTTPie:命令行HTTP客户端。
```Shell
- $ http --header http://www.scu.edu.cn
+ pip3 install httpie
+ ```
+
+ ```Shell
+ http --header http://www.scu.edu.cn
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, max-age=600
@@ -136,6 +140,10 @@ HTTP响应(响应行+响应头+空行+消息体):
4. BuiltWith:识别网站所用技术的工具。
+ ```Shell
+ pip3 install builtwith
+ ```
+
```Python
>>> import builtwith
>>> builtwith.parse('http://www.bootcss.com/')
@@ -149,6 +157,10 @@ HTTP响应(响应行+响应头+空行+消息体):
5. python-whois:查询网站所有者的工具。
+ ```Shell
+ pip3 install python-whois
+ ```
+
```Python
>>> import whois
>>> whois.whois('baidu.com')
@@ -158,13 +170,10 @@ HTTP响应(响应行+响应头+空行+消息体):
6. robotparser:解析robots.txt的工具。
```Python
-
>>> from urllib import robotparser
>>> parser = robotparser.RobotFileParser()
>>> parser.set_url('https://www.taobao.com/robots.txt')
>>> parser.read()
- >>> parser.can_fetch('Hellokitty', 'http://www.taobao.com/article')
- False
>>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/article')
True
>>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/product')
@@ -200,8 +209,8 @@ import ssl
from pymysql import Error
-# 通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8)
def decode_page(page_bytes, charsets=('utf-8',)):
+ """通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8)"""
page_html = None
for charset in charsets:
try:
@@ -213,8 +222,8 @@ def decode_page(page_bytes, charsets=('utf-8',)):
return page_html
-# 获取页面的HTML代码(通过递归实现指定次数的重试操作)
def get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)):
+ """获取页面的HTML代码(通过递归实现指定次数的重试操作)"""
page_html = None
try:
page_html = decode_page(urlopen(seed_url).read(), charsets)
@@ -226,14 +235,14 @@ def get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)):
return page_html
-# 从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定)
def get_matched_parts(page_html, pattern_str, pattern_ignore_case=re.I):
+ """从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定)"""
pattern_regex = re.compile(pattern_str, pattern_ignore_case)
return pattern_regex.findall(page_html) if page_html else []
-# 开始执行爬虫程序并对指定的数据进行持久化操作
def start_crawl(seed_url, match_pattern, *, max_depth=-1):
+ """开始执行爬虫程序并对指定的数据进行持久化操作"""
conn = pymysql.connect(host='localhost', port=3306,
database='crawler', user='root',
password='123456', charset='utf8')
@@ -268,6 +277,7 @@ def start_crawl(seed_url, match_pattern, *, max_depth=-1):
def main():
+ """主函数"""
ssl._create_default_https_context = ssl._create_unverified_context
start_crawl('http://sports.sohu.com/nba_a.shtml',
r']+test=a\s[^>]*href=["\'](.*?)["\']',
@@ -276,10 +286,9 @@ def main():
if __name__ == '__main__':
main()
-
```
-由于使用了MySQL实现持久化操作,所以要先启动MySQL服务器再运行该程序。
+由于使用了MySQL实现持久化操作,所以要先启动MySQL服务器并创建名为`crawler`的数据库和名为`tb_result`的二维表才能运行该程序。
### 爬虫注意事项
@@ -287,7 +296,7 @@ if __name__ == '__main__':
1. 处理相对链接。有的时候我们从页面中获取的链接不是一个完整的绝对链接而是一个相对链接,这种情况下需要将其与URL前缀进行拼接(`urllib.parse`中的`urljoin()`函数可以完成此项操作)。
-2. 设置代理服务。有些网站会限制访问的区域(例如美国的Netflix屏蔽了很多国家的访问),有些爬虫需要隐藏自己的身份,在这种情况下可以设置使用代理服务器,代理服务器有免费(如[西刺代理](http://www.xicidaili.com/)、[快代理](https://www.kuaidaili.com/free/))和付费两种(如[讯代理](http://www.xdaili.cn/)、[阿布云代理](https://www.abuyun.com/)),付费的一般稳定性和可用性都更好,可以通过`urllib.request`中的`ProxyHandler`来为请求设置代理。
+2. 设置代理服务。有些网站会限制访问的区域(例如美国的Netflix屏蔽了很多国家的访问),有些爬虫需要隐藏自己的身份,在这种情况下可以设置使用代理服务器,代理服务器有免费的服务器和付费的商业服务器,但后者稳定性和可用性都更好,强烈建议在商业项目中使用付费的代理服务器。可以通过修改`urllib.request`中的`ProxyHandler`来为请求设置代理服务器。
3. 限制下载速度。如果我们的爬虫获取网页的速度过快,可能就会面临被封禁或者产生“损害动产”的风险(这个可能会导致吃官司且败诉),可以在两次下载之间添加延时从而对爬虫进行限速。
@@ -305,7 +314,7 @@ if __name__ == '__main__':
web_page = urllib.request.urlopen(request, context=context)
```
- - 设置全局的取消证书验证
+ - 设置全局性取消证书验证
```Python
import ssl
diff --git "a/Day66-75/67.\346\225\260\346\215\256\351\207\207\351\233\206\345\222\214\350\247\243\346\236\220.md" "b/Day66-75/67.\346\225\260\346\215\256\351\207\207\351\233\206\345\222\214\350\247\243\346\236\220.md"
index de832feae8d9bbb1d0bd752a07f5ee8f2239b7de..52227ae3fc85eff47eddc3c343e5c4666ac51541 100644
--- "a/Day66-75/67.\346\225\260\346\215\256\351\207\207\351\233\206\345\222\214\350\247\243\346\236\220.md"
+++ "b/Day66-75/67.\346\225\260\346\215\256\351\207\207\351\233\206\345\222\214\350\247\243\346\236\220.md"
@@ -1,53 +1,91 @@
## 数据采集和解析
-通过[《网络爬虫和相关工具》](./01.网络爬虫和相关工具.md)一文,我们已经了解到了开发一个爬虫需要做的工作以及一些常见的问题,至此我们可以对爬虫开发需要做的工作以及相关的技术做一个简单的汇总,这其中可能会有一些我们之前没有使用过的第三方库,不过别担心,这些内容我们稍后都会一一讲到。
+通过上一个章节的讲解,我们已经了解到了开发一个爬虫需要做的工作以及一些常见的问题,下面我们给出一个爬虫开发相关技术的清单以及这些技术涉及到的标准库和第三方库,稍后我们会一一介绍这些内容。
-1. 下载数据 - urllib / requests / aiohttp。
-2. 解析数据 - re / lxml / beautifulsoup4(bs4)/ pyquery。
-3. 缓存和持久化 - pymysql / sqlalchemy / peewee/ redis / pymongo。
-4. 生成数字签名 - hashlib。
-5. 序列化和压缩 - pickle / json / zlib。
-6. 调度器 - 进程(multiprocessing) / 线程(threading) / 协程(coroutine)。
+1. 下载数据 - **urllib** / **requests** / **aiohttp**。
+2. 解析数据 - **re** / **lxml** / **beautifulsoup4** / **pyquery**。
+3. 缓存和持久化 - **pymysql** / **sqlalchemy** / **peewee**/ **redis** / **pymongo**。
+4. 生成数字签名 - **hashlib**。
+5. 序列化和压缩 - **pickle** / **json** / **zlib**。
+6. 调度器 - 多进程(**multiprocessing**) / 多线程(**threading**)。
-### HTML页面分析
+### HTML页面
```HTML
-
-
-
- 首页
-
-
- Hello, world!
- 这是一个神奇的网站!
-
-
-
这是一个例子程序
-
静夜思
-
床前明月光
-
疑似地上霜
-
举头望明月
-
-
- 腾讯网
-
-
-
-
-
- 姓名 |
- 上场时间 |
- 得分 |
- 篮板 |
- 助攻 |
-
-
-
+
+
+ Home
+
+
+
+
+
+
+
+
+
+ Japanese Vegetarian
+ Five week course in London
+
+ A five week introduction to traditional Japanese vegetarian meals, teaching you a selection of rice and noodle dishes.
+
+
+
+
+ Sauces Masterclass
+ One day workshop
+
+ An intensive one-day course looking at how to create the most delicious sauces for use in a range of Japanese cookery.
+
+
+
+
+
+
+
```
-如果你对上面的代码并不感到陌生,那么你一定知道HTML页面通常由三部分构成,分别是用来承载内容的Tag(标签)、负责渲染页面的CSS(层叠样式表)以及控制交互式行为的JavaScript。通常,我们可以在浏览器的右键菜单中通过“查看网页源代码”的方式获取网页的代码并了解页面的结构;当然,我们也可以通过浏览器提供的开发人员工具来了解网页更多的信息。
+如果你对上面的代码并不感到陌生,那么你一定知道HTML页面通常由三部分构成,分别是用来承载内容的Tag(标签)、负责渲染页面的CSS(层叠样式表)以及控制交互式行为的JavaScript。通常,我们可以在浏览器的右键菜单中通过“查看网页源代码”的方式获取网页的代码并了解页面的结构;当然,我们也可以通过浏览器提供的开发人员工具来了解更多的信息。
#### 使用requests获取页面
@@ -83,28 +121,90 @@
> 说明:关于requests的详细用法可以参考它的[官方文档](http://docs.python-requests.org/zh_CN/latest/user/quickstart.html)。
-### 四种采集方式
+### 页面解析
-#### 四种采集方式的比较
+#### 几种解析方式的比较
-| 抓取方法 | 速度 | 使用难度 | 备注 |
-| ------------- | ------------------------- | -------- | ------------------------------------------ |
-| 正则表达式 | 快 | 困难 | 常用正则表达式
在线正则表达式测试 |
-| lxml | 快 | 一般 | 需要安装C语言依赖库
唯一支持XML的解析器 |
-| BeautifulSoup | 较快/较慢(取决于解析器) | 简单 | |
-| PyQuery | 较快 | 简单 | Python版的jQuery |
+| 解析方式 | 对应的模块 | 速度 | 使用难度 | 备注 |
+| -------------- | ------------- | ------ | -------- | ------------------------------------------- |
+| 正则表达式解析 | re | 快 | 困难 | 常用正则表达式
在线正则表达式测试 |
+| XPath解析 | lxml | 快 | 一般 | 需要安装C语言依赖库
唯一支持XML的解析器 |
+| CSS选择器解析 | bs4 / pyquery | 不确定 | 简单 | |
> 说明:BeautifulSoup可选的解析器包括:Python标准库(html.parser)、lxml的HTML解析器、lxml的XML解析器和html5lib。
-#### 使用正则表达式
+#### 使用正则表达式解析页面
如果你对正则表达式没有任何的概念,那么推荐先阅读[《正则表达式30分钟入门教程》](),然后再阅读我们之前讲解在Python中如何使用正则表达式一文。
-#### 使用XPath和Lxml
+#### XPath解析和lxml
-#### BeautifulSoup的使用
+XPath是在XML文档中查找信息的一种语法,它使用路径表达式来选取XML文档中的节点或者节点集。这里所说的XPath节点包括元素、属性、文本、命名空间、处理指令、注释、根节点等。
+
+```XML
+
+
+
+ Harry Potter
+ 29.99
+
+
+ Learning XML
+ 39.95
+
+
+```
+对于上面的XML文件,我们可以用如下所示的XPath语法获取文档中的节点。
+
+| 路径表达式 | 结果 |
+| --------------- | ------------------------------------------------------------ |
+| bookstore | 选取 bookstore 元素的所有子节点。 |
+| /bookstore | 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
+| bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
+| //book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
+| bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
+| //@lang | 选取名为 lang 的所有属性。 |
+
+在使用XPath语法时,还可以使用XPath中的谓词。
+
+| 路径表达式 | 结果 |
+| ---------------------------------- | ------------------------------------------------------------ |
+| /bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
+| /bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
+| /bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
+| /bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
+| //title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
+| //title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
+| /bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
+| /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
+
+XPath还支持通配符用法,如下所示。
+
+| 路径表达式 | 结果 |
+| ------------ | --------------------------------- |
+| /bookstore/* | 选取 bookstore 元素的所有子元素。 |
+| //* | 选取文档中的所有元素。 |
+| //title[@*] | 选取所有带有属性的 title 元素。 |
+
+如果要选取多个节点,可以使用如下所示的方法。
+
+| 路径表达式 | 结果 |
+| -------------------------------- | ------------------------------------------------------------ |
+| //book/title \| //book/price | 选取 book 元素的所有 title 和 price 元素。 |
+| //title \| //price | 选取文档中的所有 title 和 price 元素。 |
+| /bookstore/book/title \| //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
+
+> 说明:上面的例子来自于菜鸟教程网站上[XPath教程](),有兴趣的读者可以自行阅读原文。
+
+当然,如果不理解或者不太熟悉XPath语法,可以在Chrome浏览器中按照如下所示的方法查看元素的XPath语法。
+
+![](./res/douban-xpath.png)
+
+
+
+### BeautifulSoup的使用
BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航、查找、修改文档的方式。
@@ -121,12 +221,10 @@ BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库。它
> 说明:更多内容可以参考BeautifulSoup的[官方文档](https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html)。
-#### PyQuery的使用
+### PyQuery的使用
pyquery相当于jQuery的Python实现,可以用于解析HTML网页。
-
-
### 实例 - 获取知乎发现上的问题链接
```Python
diff --git "a/Day66-75/72.Scrapy\345\205\245\351\227\250.md" "b/Day66-75/72.Scrapy\345\205\245\351\227\250.md"
index 56ab2d18e0185842ef3897f76b0276e3c6b80069..aaaab43f73cd573fa35f453fbf73f066184f40b5 100644
--- "a/Day66-75/72.Scrapy\345\205\245\351\227\250.md"
+++ "b/Day66-75/72.Scrapy\345\205\245\351\227\250.md"
@@ -302,76 +302,3 @@ Scrapy的整个数据处理流程由Scrapy引擎进行控制,通常的运转
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
```
-### 补充说明
-
-#### XPath语法
-
-1. XPath路径表达式:XPath使用路径表达式来选取XML文档中的节点或者节点集。
-
-2. XPath节点:元素、属性、文本、命名空间、处理指令、注释、根节点。
-
-3. XPath语法。(注:下面的例子来自于[菜鸟教程](http://www.runoob.com/)网站的[XPath教程](http://www.runoob.com/xpath/xpath-syntax.html)。)
-
- XML文件。
-
- ```XML
-
-
-
-
-
- Harry Potter
- 29.99
-
-
-
- Learning XML
- 39.95
-
-
-
- ```
- XPath语法。
-
- | 路径表达式 | 结果 |
- | --------------- | ------------------------------------------------------------ |
- | bookstore | 选取 bookstore 元素的所有子节点。 |
- | /bookstore | 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
- | bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
- | //book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
- | bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
- | //@lang | 选取名为 lang 的所有属性。 |
-
- XPath谓词。
-
- | 路径表达式 | 结果 |
- | ---------------------------------- | ------------------------------------------------------------ |
- | /bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
- | /bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
- | /bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
- | /bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
- | //title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
- | //title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
- | /bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
- | /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
-
- 通配符用法。
-
- | 路径表达式 | 结果 |
- | ------------ | --------------------------------- |
- | /bookstore/* | 选取 bookstore 元素的所有子元素。 |
- | //* | 选取文档中的所有元素。 |
- | //title[@*] | 选取所有带有属性的 title 元素。 |
-
- 选取多个路径。
-
- | 路径表达式 | 结果 |
- | -------------------------------- | ------------------------------------------------------------ |
- | //book/title \| //book/price | 选取 book 元素的所有 title 和 price 元素。 |
- | //title \| //price | 选取文档中的所有 title 和 price 元素。 |
- | /bookstore/book/title \| //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
-
-#### 在Chrome浏览器中查看元素XPath语法
-
-![](./res/douban-xpath.png)
-
diff --git a/README.md b/README.md
index 58e09073e6cd22c1fcaba992f933c6cc2283a64f..b0db839e6d59f1083638898472dd1c59a1c5558b 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,11 @@
> 作者:骆昊
>
-> 最近有很多想学习Python的小伙伴申请单独加我微信和QQ,因为我自己平时也很忙,没办法一一解答大家的问题,我创建了**Python100天学习交流7群**(之前的6个群已经基本满员),群号为**784430256**,二维码在下方。我的同事和朋友也在这个群里,他们很多都是优秀的Python开发者,有丰富的商业项目经验,我们在闲暇的时候会为大家解答问题,内容包括但不限于Python语言基础、Web后端开发、网络数据采集、数据分析和机器学习。我们希望这个群能够慢慢汇集资深人士和行业大咖,营造一个相对纯粹的技术社区。以后我们争取每周做一次视频直播,以专题的形式分享Python开发的点点滴滴,同时还会不定期的举办线上和线下的技术交流和分享活动,小伙伴们可以加群进行交流。创作不易,感谢各位小伙伴的打赏支持,这些钱不会用于购买咖啡而是捐赠给支教组织([点击](./更新日志.md)了解捐赠情况)。感谢**北京千锋互联科技有限公司Python教学部**对[公开课](https://ke.qq.com/course/406954)的支持。
+> 最近有很多想学习Python的小伙伴单独加我微信和QQ,因为我自己平时也很忙,没办法一一解答大家的问题,我创建了**Python100天学习交流8群**(之前创建的几个交流群已经全部满员),新的交流群群号为**789050736**,二维码在下方。群里有优秀的Python开发者和行业大咖,也有刚刚开始接触Python的小白,我们希望借助这个项目,为大家提供一个沟通和交流的平台,我自己也会在闲暇的时候为大家解答问题,交流的内容包括但不限于Python语言基础、Web后端开发、网络数据采集、数据分析和机器学习。我们希望营造一个相对纯粹的技术社区,争取每周做一次专题视频直播,不定期的举办线上和线下的技术交流和分享活动,对Python感兴趣的小伙伴们可以加群进行交流。创作不易,感谢大家的打赏支持,这些钱不会用于购买咖啡而是捐赠给支教组织([点击](./更新日志.md)了解捐赠情况)。感谢**北京千锋互联科技有限公司Python教学部**对[公开课](https://ke.qq.com/course/406954)提供的支持。
-![](./res/qq_group.png)
+![](./res/python_qq_group.png)
-> **温馨提示**:Python100天学习交流**6群已满**,请加入新群!
+> **温馨提示**:Python100天学习交流7群已满员,请加入新的交流群。
### Python应用领域和就业形势分析
diff --git a/res/python_qq_group.png b/res/python_qq_group.png
new file mode 100644
index 0000000000000000000000000000000000000000..503e15a01c28f8b7498a47927f3ab2f6750668cd
Binary files /dev/null and b/res/python_qq_group.png differ
diff --git a/res/qq_group.png b/res/qq_group.png
deleted file mode 100644
index 49bd1c8d7e2d87a9da5a0866ac0647412aabdda2..0000000000000000000000000000000000000000
Binary files a/res/qq_group.png and /dev/null differ
diff --git "a/\344\275\277\347\224\250Hexo\346\220\255\345\273\272\350\207\252\345\267\261\347\232\204\345\215\232\345\256\242.md" "b/\344\275\277\347\224\250Hexo\346\220\255\345\273\272\350\207\252\345\267\261\347\232\204\345\215\232\345\256\242.md"
new file mode 100644
index 0000000000000000000000000000000000000000..70df83cddb5011b59a517a29bbb35db8e40bc2c1
--- /dev/null
+++ "b/\344\275\277\347\224\250Hexo\346\220\255\345\273\272\350\207\252\345\267\261\347\232\204\345\215\232\345\256\242.md"
@@ -0,0 +1,38 @@
+## 使用Hexo搭建自己的博客
+
+对于一个程序员来说,搭建一个属于自己的博客平台是非常有意义的事情。首先,博客可以记录自己的成长历程,也是对自己一段时间学习和工作的总结和沉淀;其他,通过博客可以营销自己,增强自己在互联网或行业内的影响力,为将来更好的职业生涯打一个坚实的基础。前几年有一本名为《软技能 - 代码之外的生存指南》的畅销书,我记得书中有这么一段话:“流行乐队的音乐才华可能并不比夜店驻场乐队高多少,他们为什么就可以在全世界巡回演出,创造一个又一个白金记录?……你的营销做得越好,你的才华才能表现得淋漓尽致。”
+
+这里顺便啰嗦两句,在互联网如此发达的今天,我们应该如何营销自己呢?自我营销首先要从打造个人品牌做起,对于程序员来说,最容易去做好的一件事情还是搭建自己的博客。博客相当于是你在互联网上的一个基地,尤其是当你拥有了属于自己的独立博客后,你可以做很多自己想做的事情,既可以传达自己的思想,又可以提升自己的影响力,当然如果你的博客经营得非常好,你可以从中获利。当然,除了博客,直播、视频网站、投稿、写书、技术活动都是可选的自我营销方式。当然,做自我营销也需要持之以恒,三天打鱼两天晒网是很难有什么收获的。
+
+### Hexo概述
+
+Hexo是一个快速、简洁且高效的博客框架,它能够将[Markdown格式]()的文档渲染成漂亮的网页,这样我们就可以在很短的时间内迅速的创建出网站的静态内容,而Markdown格式对程序员来说相信并不陌生。要想使用Hexo来搭建自己的博客,我实在想不出有什么教程比[官方文档]()更好,强烈建议大家阅读官方文档来了解Hexo,下面我只做一个简要的使用说明。
+
+> 说明:**Markdown**是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,同时也对图片、图表、数学公式提供了支持,可以用来书写电子书、软件文档等,同时也可以非常方便的转换为HTML页面或者是PDF文档。
+
+要使用Hexo,首先得确保计算机上已经安装了[node.js]()环境和[git]()环境,前者是一个能够在服务器端运行JavaScript代码的环境,后者是版本控制工具。如果没有安装node.js和git的经验,建议参考官方文档上的讲解,安装完成后,我们可以通过下面的命令来确认node.js环境以及它的包管理工具是否安装成功。
+
+```Shell
+node --version
+npm --version
+```
+
+可以通过下面的命令来检查是否安装了git环境。
+
+```Shell
+git --version
+```
+
+我们可以使用npm来安装Hexo,npm是node.js的包管理工具,跟Python的pip工具作用一样,可以用它来安装依赖库和三方工具。在第一次使用npm的时候,我们可以先将npm的下载源更换为国内的淘宝镜像,这样下载的速度会有非常显著的提升。
+
+```Shell
+npm config set registry https://registry.npm.taobao.org
+```
+
+接下来我们就通过npm来安装Hexo,命令如下所示。
+
+```Shell
+npm install -g hexo-cli
+```
+
+安装成功后,就可以使用Hexo来创建一个博客文件夹。
\ No newline at end of file