From 2b8745ab364593387bba5df6c935087b48b048ea Mon Sep 17 00:00:00 2001 From: Guang Chen Date: 2020年5月19日 21:02:52 +0800 Subject: [PATCH 01/13] QA 11 added --- README.md | 2 ++ questions/question_011.md | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 questions/question_011.md diff --git a/README.md b/README.md index e335e12..e1dbcb4 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ | 2020年5月8日 | 第10讲:解码之路
摘要:候选解码结果的筛选思路——加字典/常用词词典/高频词排序词典、用循环遍历/列表推导/filter()函数结合lambda内联函数/集合运算四种方式实现数据过滤、用词典缩减/递归深度缩减实现解码优化、字符级与单词级解码、用空间换时间、递归思维、类比思维等。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_10.ipynb)
![第十课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_10_001.jpg)| [L10.1](https://www.bilibili.com/video/av92186118?p=25) | | - | 第10讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_010.md))
摘要:递归运行过程分析方法、利用上下文信息进行候选解码结果筛选、如何用while循环代替递归、lambda内联函数还能用于哪些Python内置函数、语法信息是否可用于筛选、filter()函数的用法、用时间换空间vs.用空间换时间、是否可用不同的词频文件、迭代器的使用、iter()函数和\_\_iter\_\_()函数、是否可结合哈夫曼编码、能否用常用句子库解码、自己上手编程困难该怎么办、加快解码速度的思路、生成器的使用、迭代器转换为列表是否会丢失信息、集合的交集并集计算、程序如何实现分级封装、应该如何添加词频文件不包含的词等。 | [L10.2](https://www.bilibili.com/video/av92186118?p=26) | | 2020年5月15日 | 第11讲:反向最大匹配解码与爬虫初步
摘要:基于优先匹配长词的想法,用递归实现反向最大匹配解码;初步了解爬虫的基本概念、基本流程;采、抽、存三步走的简单实现;了解requests使用、回顾正则表达式的配置和re正则库的使用。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_11.ipynb)
![第十一课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_11_001.jpg)| [L11.1](https://www.bilibili.com/video/av92186118?p=27) | +| - | 网络爬虫第0课:浏览器背后干的那些事儿
摘要:了解、开发爬虫必须了解的HTTP/HTML知识,从输入网址到看见网页,浏览器背地里干的那些事儿。 | [L11.2](https://www.bilibili.com/video/av92186118?p=28) | +| - | 第11讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_011.md))
摘要:爬虫有什么"高级"应用、什么样的网站是"软柿子"、正向最大匹配能用吗、pyquery与jQuery、爬虫难吗、图片影片怎么爬、玩转正则需要记住吗、网站反爬有哪些手段、爬网页要遵守的规定、递归过程中最小值的定义、网站是不是都能爬、requests的header部分是做什么的、百度网分享链接和分析密码的爬取策略、正则表达式如何匹配"所有符号"、get和post的区别、爬虫与数据可视化、爬虫翻页链接的处理、学爬虫有什么好课程、对课上的"干货"力不从心怎么办、有没有可能不分析页面源码也能做抽取、反爬常用手段、验证码问题怎么解决等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=29) | 学习资源推荐: 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) diff --git a/questions/question_011.md b/questions/question_011.md new file mode 100644 index 0000000..a429cce --- /dev/null +++ b/questions/question_011.md @@ -0,0 +1,39 @@ +| 第11讲答疑 问题列表 | +|--------------| +|爬虫有什么高级的应用| +|如何判断一个网站是不是爬虫的"软柿子"呢?| +|有没有正向最大匹配,为什么不用呢?| +|pyquery与jQuery的区别| +|爬虫难吗| +|图片影片应该怎样爬取| +|正则的用法需要记到脑子里吗?还是只要用的时候能找到怎么用然后正确使用就好?| +|想了解一下,一般网站会有什么阻碍爬虫爬取数据的举措吗?| +|还是不太明白找到网站后的过程。。。| +|请问老师摩尔斯编码除了引入高频词汇表以外,还有什么外源数据表可以更好的应用于摩尔斯编码吗| +|爬网页是否需要遵守一些规定| +|在第一个递归中,start的最小值为什么是morse_seg-max_morse_len| +|网站都可以用爬虫去获取数据吗,requests里的headers是用来干什么的?| +|可以直接用get函数获取部分内容,而不是全部?| +|如何在不知道密码情况下爬别人分享的加密的百度网盘分享链接,然后通过枚举测试以最终得到密码?| +|请问除了[\S\s]能表示所有符号外,还有那些常用表达能在正则中表示所有符号| +|爬虫可采集数据的范围?| +|为什么有些网站相对"软",怎么判别| +|有点不明白get和post的差别| +|老师您好,可以在说Python爬虫的时候说说可视化么(゚o゚;网络上的图都好漂亮,但我做不出来( ́;(;`)| +|如果被爬网页是多页的, 爬虫可不可以自动跳转页面. 而且有的网页的跳转链接并没有在html里面找到, 这时应该怎样处理| +|想系统地学习爬虫,想问老师有没有推荐的课程。
还想问一下这节课的方法对一些防爬虫性能好的网站仍然可以吗?| +|那个max(len(morse_seg)和那个max(moorse_len)分别是什么意思啊,为什么是前面减去后面的| +|想学如何用爬虫爬图片| +|老师讲的东西很干货,但是很多 感觉自己实际掌握有困难怎么办| +|爬的好像只能是一个网页中的,有点像审查元素,查看源代码,是不是还可以进一步爬取更多,同时减少时间?| +|反向最大匹配可能会因为符号 或者某些 短单词 等等报错 能不能再使用正向和其他方式同时匹配解码配合得出正确结论| +|能不能从词典文件入手提升替换效率| +|怎么编一些反爬虫的程序呢| +|正则到python里面character group自动分出来吗| +|满足什么条件的网站可以用爬虫获取信息?| +|那个span斜杠前加个反斜杠会咋样,回放很多遍没听清....windows用户要把cat改成more?还是相同发音别的单词?| +|爬虫要怎么解决验证码问题呢?| +|在网页上找要用的信息还是太麻烦了吧,就是找价格的时候还得自己浏览一遍源代码?这有没有啥简便方法?| +|怎么分辨哪种网站是"软柿子"| +|爬虫的具体作用| +|如何更改新建文件储存位置| \ No newline at end of file From 49af51c45e0d64cf0308b2241d0bb88e6c43d161 Mon Sep 17 00:00:00 2001 From: Guang Chen Date: 2020年5月22日 15:07:13 +0800 Subject: [PATCH 02/13] class 12 added --- README.md | 1 + code/Python_Class_12.ipynb | 389 +++++++++++++++++++++++++++++++++++++ images/class_12_001.jpg | Bin 0 -> 83438 bytes questions/question_012.md | 36 ++++ 4 files changed, 426 insertions(+) create mode 100644 code/Python_Class_12.ipynb create mode 100644 images/class_12_001.jpg create mode 100644 questions/question_012.md diff --git a/README.md b/README.md index e1dbcb4..fee8d39 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ | 2020年5月15日 | 第11讲:反向最大匹配解码与爬虫初步
摘要:基于优先匹配长词的想法,用递归实现反向最大匹配解码;初步了解爬虫的基本概念、基本流程;采、抽、存三步走的简单实现;了解requests使用、回顾正则表达式的配置和re正则库的使用。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_11.ipynb)
![第十一课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_11_001.jpg)| [L11.1](https://www.bilibili.com/video/av92186118?p=27) | | - | 网络爬虫第0课:浏览器背后干的那些事儿
摘要:了解、开发爬虫必须了解的HTTP/HTML知识,从输入网址到看见网页,浏览器背地里干的那些事儿。 | [L11.2](https://www.bilibili.com/video/av92186118?p=28) | | - | 第11讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_011.md))
摘要:爬虫有什么"高级"应用、什么样的网站是"软柿子"、正向最大匹配能用吗、pyquery与jQuery、爬虫难吗、图片影片怎么爬、玩转正则需要记住吗、网站反爬有哪些手段、爬网页要遵守的规定、递归过程中最小值的定义、网站是不是都能爬、requests的header部分是做什么的、百度网分享链接和分析密码的爬取策略、正则表达式如何匹配"所有符号"、get和post的区别、爬虫与数据可视化、爬虫翻页链接的处理、学爬虫有什么好课程、对课上的"干货"力不从心怎么办、有没有可能不分析页面源码也能做抽取、反爬常用手段、验证码问题怎么解决等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=29) | +| 2020年5月22日 | 第12讲:爬虫框架初步设计与B站豆瓣初步尝试
摘要:构建爬虫基础类(框架),了解框架、脚手架和库的差别,复习类的设计和构建,对B站和豆瓣的排行榜进行采集,构建完整的信息抽取用正则表达式,熟悉RegexBuilder等正则调试工具的使用,用copy as Curl->requests技巧"克隆"浏览器的访问请求。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_12.ipynb)
![第十二课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_12_001.jpg)| [L12.1](https://www.bilibili.com/video/av92186118?p=30) | 学习资源推荐: 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) diff --git a/code/Python_Class_12.ipynb b/code/Python_Class_12.ipynb new file mode 100644 index 0000000..be57ac4 --- /dev/null +++ b/code/Python_Class_12.ipynb @@ -0,0 +1,389 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.采——网页的采集" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "import requests" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "req = requests.get('https://wap.zol.com.cn/top/cell_phone/hot.html')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2.抽——信息的抽取" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "result = re.findall(\n", + " '

(.*?)<\\/p>[\\S\\s]*?(.*?)<\\/span>',\n", + " req.text\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.存——保存采集结果" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "with open('mobile.txt', 'w') as f:\n", + " for item in result:\n", + " f.write(item[0] + ' ' + item[1] + '\\n')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cat mobile.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 基础爬虫类(框架)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern):\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 对zol.com.cn进行测试" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "crawler = MyCrawler('mobile.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "CONTENT = crawler.download('https://wap.zol.com.cn/top/cell_phone/hot.html')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "crawler.crawl(\n", + " 'https://wap.zol.com.cn/top/cell_phone/hot.html', \n", + " '

(.*?)<\\/p>[\\S\\s]*?(.*?)<\\/span>'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cat mobile.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 对bilibili进行测试" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler = MyCrawler('bilibili.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "c = b_crawler.download('https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3')" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "info = b_crawler.extract(\n", + " c, \n", + " '(.*?)<\\/a>.*?<\\/i>(.*?)<\\/span>.*?<\\/i>(.*?).*?<\\/i>(.*?).*?

(\\d+)<\\/div>'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler.crawl(\n", + " 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3',\n", + " '(.*?)<\\/a>.*?<\\/i>(.*?)<\\/span>.*?<\\/i>(.*?).*?<\\/i>(.*?).*?
(\\d+)<\\/div>',\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "!rm bilibili.txt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open('bilibili.txt','r',encoding='utf-8') as f:\n", + " lines = f.read()\n", + " for line in lines.split('\\n'):\n", + " print(line)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cat bilibili.txt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler.crawl(\n", + " 'https://www.bilibili.com/ranking?spm_id_from=333.851.b_7072696d61727950616765546162.3',\n", + " '(.*?)<\\/a>.*?<\\/i>(.*?)<\\/span>.*?<\\/i>(.*?).*?<\\/i>(.*?).*?
(\\d+)<\\/div>'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 对豆瓣进行测试" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler = MyCrawler('douban_book.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "''" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b_crawler.download('https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 用curl.trillworks.com实现Chrome网络请求的"克隆"" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "\n", + "\n", + "headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + "}\n", + "\n", + "response = requests.get('https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C', headers=headers)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "47944" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(response.text)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'Neural Networks and Deep Learning' in response.text" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/images/class_12_001.jpg b/images/class_12_001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d78b170fadfea01fb89cafef239dc0a888ed1ec6 GIT binary patch literal 83438 zcmeFYcUV(R*Dt(7Lhrpw=pa>^AT1zWM2ZU1jPxd5ii!y$MX3r33JMAWA_CH@gkD5N zKtMoBLT{3QLWB^`#{0SN=RMDRecyS{_db7o=Un%|WPW??HEU+Anc1^u&+NmmhqD07 z86#6800IGk``{mNhy~INBfLETz}y^=1^|EtfI;{GN)Ul8fDVNJFKh&n0-(R?6aWzK z4Z!}va}G?80x0cwon?Z#9``odW}}Qm_DkpZ~RBYva>Gm+b6?sOQ02umDt`Mm)~0A%S|9 zmS>M-{+a%k|JTpX=x@z{VYwq&f06%dfX&T4#1%A+BgpRJ7UJp$;#L5FMY{$DUjqOt z1CTBnel73_dx4lE7_1ANa_o94>0ドルm%n)~SnGp4^0svDdNEZro z^#tWG&4c)aznix|05EfaSjW}N*$u=OKrHL7ドルjT55Kr99F2ZHz&h}B*GgG|r=fSsLP z{*v$P?D-e|LoYBVSP28~kie_X*MDF9JAeGHhJv>H9VEbC2CrZfYcK_Mf_(K2FgwBw zAYS)(IcEW4u(v^o-k^4WUJwKH=tUU*4X+EfAe{~Xpmbs0Hb-NJ3B(*BzUPnX1J(g5a>Gmii2j== zIMn*6{$e0q-QC~#G>F0aKpj1TjgE9b;t%u-0nzWeLF2rqc+2x3ro=qGpoi~rCUIvsfJ^if$ydGUc) ze~%N8A4cPT)%b`m0%E?9u=D@O3)8w5eBp==))RI%@S5e34Z(WCuJ|~gu>>(#A6OW0 z7SIO_03je0j4nU`-~)JnTCZCNul~4W1ULi1fG6M%$o+%zXAaxncl^QM^S}*Y1MmlV zLjKBk`uAOTAPl4*{6+mEuN>g<`)=6p9koijsb`s523!tnlqy5g=j~tu8(i_% zXX&nBU9W=i=-z*(>493E1xr2R3jI^A5c8j$REAUrR3=nLRL5a_FddjC>@4`J3q~cF zI_%V+wf!eQ==| z6a%e?et^C^!v84W=yw}>{#Baw@A~+H?c)6x&!74_gOsB(k9tAKiINj5CrJO00$g*C zxCZuHKtCYxda$>r*EJzMa29YEGWBzTOj^>mj9stt9vz&W7zk!xsh*dOv>M+qhPG++it6fYnMhyqfe zMoPd*Koigf41qI%1#khd11^KT&I|0%!9X|=3ET$afJAUkegtFzxj;Vf3Md6CfjXcW zXal-|e&91O0!)JaX8~9P@W2kR4}n0aA&d}q2rmQ<5r@b?lpyl59f%?1ew{do2e|_a zg!n^3A(4fowtcD4-M!6dV-CC?qHpDAXzR zD9k7>P&iR|QUp=lpopPJp?FM@NAZTDmZFWKpJIe!mSTBP&ueNR3B;q zwTF5@gP|yB0yG1f2Q7m(f-OA^orSJLf5E6=>@Xpi9N33VU>9Moupk%;mITX!y@J)k zI$^^wEDR4LQ!-KtP|8qhP?}O+qV%K;r;MY_pe&@Uq3i-j(*orV6%`d1l_ZrKI2!G! ze5h_xB~d-2DyM3t8l;+|`bkYq%}Xsqtxat~?M!`*I*4ドルY^&4so^$_&}HIas%22P_y zV?<+5<4+s!lr@*eriesrw{gb>mW5WFR)f}p){XW$Z7S_c+D6&|+6CHuI#xPKI&HcO zbUt*q=^oRS(RI;%quZvZrx&3=MQ=s#O&>-7nEow&FFlt27XurEG=n~aBSR=d3PTY? zE5kU$HX|dW1fwpaJ>xaT6vkr44#sIlA`?54Jd-Jt8xxu-o2iy*i0L~sEwebY9`j}9 z8_XHZRm=m->nyY^5-j>G&MYXFY?cO=F_xdK?5v8c7OZ}(Nvy9~`&gIRsM#dg4B6b+ zV%YN8I@speq3ojU`s}Xkci3ODcd;*UP;p3dm~!}VByyB;eB!`!vT>?#+Hgj2W^=yd zoaKUYNpP8RUFAyUs^l8w+T%XPt;g-oeUH10dx(3Nho486$DJpEr<`ymxocbi*o1qj z_W^Gm?-U=5Pnyq)FPtxjuZwS;pMzhM-<3aszmk7kfi>i8z*^v@K)%2SfuF|&j~O2e zJoe;R$FX%mEcDN4Q8~zZEfv*a23h4=56?!bxDTEgm5H=AG6@DT7 zNqApGQskmYv`D$glqj93x~PZfL(z6oyck@}Tr5(oL~KHwR$N`&OFUD&M|@X8Qo>du zUZPH7S&~Q6RPu&oiR3paMk0ドル;kW`-3m*Z5&)sOoge|G${G=;RPw3l?Y^neV7%t;w< znP)PCvXru?Wc_9HWXI$f9*P6>(l3MOs zFSX{hMYNr@Uue(j2jPS;)#y5>yO(;#wOdgnwnI1EBH7z#9 zpHVw=>rAH^gV}krEHm6$>9fIS8_g-q&zPs1e>*3B&i`DU1z=%nk!~?%DQOvG*wq9ckTjp8Y)X{Oj{O7fxSDy)b!E>SE}{b{l3JN1I}sU0Va&G~3xr3YTtO z>bK*w^R}zEr?7ドルTFSP&ZVCeA3VZl+=G0t(+Nzy68sqZr1<*s9ドルa(@fr$f_%ps8t7m zzCv=gaL#l7>0;{g)CKRV@0#hl=BDfR&~3$C+da*F$wS*C&12b9+cVvB#S7t;;kE9q z@15mM@GgfZieH02o4>DrXMkWpM8II6OkiB#Y>-CKqab{+ zS#V(pB*ZDC{u&49ynhIl3XKiLhUtW5hY`bV!mA=!Bm5&iT$jFn@A}dWqZ+R>uu81zDvan!5ZbhmwPe~dm6ofiG$j_sYsm}4|rT zu_bX#alvt8@tX0ucVTzE?|!2C(&p05(`z3JJxqA`;}P;vUxrFXZYEu3Xy)wWvybbah&{Rg zgp}o#HIjWgyZouZ(|b>MpSe97%F)d!%RQExn7jAf`}x-w#xH8~B=R!ysq(|}7hl@E z>?u$$C@$nHOe{Po@-LcwW&NtNSgpADwZQAt5{i=0l9e}(Z6ドルhAl-8HYmAxqEDo=b1 zybXQ3T5+Xfw9>4yy-K~RtXjPKX$^Z#LM^2BdM&=rt8TX5u70rLOhbF4W@Am0d{a@g zaC7!M&UdLTbS*J0hnO3fpRIwd>usKGbM46X$&O1MUplQiKXsXP^>!O|cl7A>V0yKC zoBK5S8s4kFuj@bAU;9DzL(NCkk2Rl8eySZ%8>s($>T~0u)?mvJVyJD{V7U8>>6iYI zb0dSJ7e~L2IgZVKb^E$Jes!EM5jL?u8TF0wTf!8}RK~Qxbl%MIney3_v+uA5*blh# zxXC%!xwZL_dD246BI9Dl5`3w6S!ua>#c1X8s>ABSTHxCLdfW!<#?$xo->WxuH$UJn z;TH(Ogu|_*ZQkvoA1XiEe_H;W-tpVn-%TL5ドル?}pN|JAc+ySKC-PNF6~J~)2RNH!yX zJM=p|40H~5{_P7Kt-dKdz_t2T5dbjS0Ra1F(0_3FW6k%Q1Mjwp0w@EMBX?cD6#(9XQ9>7#9R&bKuKERCfI?aMuLx3(LWqa5(r*A^2nJmf;^E=; zF#w=1ドルb~C!!^8b&hld9*!L`CT0JH}EvDQ4|reXnr=b)zq07LMqqvU@If2>16(w{p1 zYYJ+vtgLdB=YL8MTLD%Y$PiUG6e0pputK1$ki$*@4(dz^Iy7MTvlIvg6h=u!O+!mZ z4>HuS02B}?lmZ5&q&#}D0J#O;2Vks}Y{H6qRP0vH)FMF~O1B@ppb#h!<0k z367?v+`1$X4`#-SH zLJtT3Znys<+imfyckffj+k#d&t_h7gm-{`{^5|a+vz68m+_-neo3w~wbwukbq=heb zpf%wXJ-7QPqBI(1w%Z=|o>3dltQCAY?hGpS_9g?}+*3e=;1pbLLdZQF{bMfkuc_}Yx|p6_pz?ko6N>blB0&m_w1C@KJAzk7 zgP3l7P>iA=>EJz+-jr&==K?l%M`K)uux@`**1~a*WFk|Sn2W_WZx|Gl4Zl5GuOTpB$#4f7*XjTPye>}1Px`;|M>d-i)bCQg0`mWg~5^i+VwF!K7` zCh@puhi~eHLaU$v@j5}&tcvI%TjozPfA#IF~Iu!*_6ks@QZoqVd#<}=v7$+azz zHYBJoxJ?ELTn$Wn(Mx%Kc3uFu(Zz{>h{RhlM^*OA!pBjvwz1>dK1V@B@cWrtsvTHfko zd=xcDkWg)A(a{#`gC~bTz#(vFVyTUpk7ドルjWr^}pftb2^`QT~PB)TT=c^J{0oVOaQ}kiU4B6oT%GT(7j}=mz zWO&esa4(OUVW~mHqFExnuH~{XlZ_|*&{d(d?YHtc>QmX;{KPyJd*kEOKQRj>0DBV& zqy#*M#9@qWJ_Kswlb(;YNcCc9H>%Cl1~;gZ<$j!kzfo~uj1eqw9*a>q^U4Q3Ww@1z z@820ec+#R2u{DX!?FisG=Ghr;Wv=9a_C!vm%2Ud(yVcjFC`KXPrB6iZy#B8Z-v2Ep z2zogD_e1f2W!JLs&K6nxQjDxoKF*A|e#N!M%&iJ;Xh`|^08*CF5`n+?sICjn>w{ql zt#@r6`q2ls7Xp#l_OZ3^ii2ca_o>+hBaOfxt}^d$Dy;Ts-zYnoq=p_Dcp>^g zBH2A@!I6ski=g4j>5ドルenW%6#9^7Jyog)cA%M{vpokr8<27?f0m<^?=+stv!tgt#rm znI@YwlbBa;1Skkf>c1We^4KbVj`YKa%+7S?-kzyOCa7R2r@G2WbcA^|zRp1;lD16c zmcQ}AdZ0{Z+NH9P^c=B^=G~ zhqiKBA5~)x1gaHfOa`T|C)c@1KeSNmBCABw9;Bm$Bi@ofpetrNo+)1(!wy`5n}$SP6op~yB_k#;i!-mYK3~nzBrajgV>MJz!lNw=J}9p2bHky$ zZmerIrOslRJLw$mlj4&Kj|$bRuY{3`0Vn zPdiPwz4i{@v8L+R-7e31@IHU(t8G=RU#|}4;8o9t+{qF}X)gqzt3EPI3ghKF*~DA><`eib=ynftht8ドルb4r}(} zGkv!TrjqV(^y-S6+KdYUCu!On8_Nf)fj(E${0Mjc2W>Wj&+)$a)SWt_-99I308@=@ zEpak#+w;T3ilufgb!s>zSzmViR`=D#Tv6;c?}F@@!rhSD^=T%Sou~~92HO*T0UGfs z7p30c;B<~gnrw_ldlztw@!x>a%2hJoxZ|y&&Jg0_l67-S{mqi>V&S1X`VH9&6bg#9 z8|JBDJ;yE3sC zVO;7x)SNgJ7x=t_T}HK{xyX`J5gMN?IK9+b#8Y}KB`h>xm5pvu3InMRbfH4~i!I%C zL~eZ1T=>RMLgN@NGk$I?Z|E9=LHl)|?BI1j6()gH34>3kQyNyfBEzxB@siotnRQA+ zIL^H%7Kdi{%A6KA)9ldhUbcC^+yl@qu4{4tN=4e|%mLIKi8Wb-s4&Zu&vOA!ehB=a z7}ByW8hf94gSiXCO70``43nvd2{Rpn%I4HYIo+$Pl=ZhKXoT;#2?e%UUukjB8I`6L zHV@9N+}#L)cQc;1A{r80jdY;I9&D8Dh0jImX0f`;p)Q@dN?fp$P(@2UhGiQgVBa3} zGMJwryk}BpXwV)=V47q^j6L>dFKM-}=u)gjt&gnX~Y zV3NIcbPU5+jbtL~I}*yfcFA7})H@>|KUNG23wZB^){PHYy2f$+s-MLwwLt}Cc4iKe zNpjekSUCS7;58r+k$#@Abnp9>nC0AwGCnz`QHOe{{?&UiVqBp%6E7^IxKY30tG6_< zo*U(8KA+1x#JQK=I`GDnQ`h!+n-wX)WYoTi>Y_JW>~_qk)F5kyEwI!jcW*&l@fYK`;U}; zQj*{!b<@o-y5q!tytr@rxaiog;}cemd6kzuo*e?hg7rzke%}mf4zuxzpezmk*i%|o z@s>_KhTP8RlcXrnsOxBs9BZ^eti6QK=?e6;!&7ExTeQ7)_YQ$}1WOlA8*#Q_U%YeB zP~}Yey4^|CFP7X#w|ikBW2$qxoH~l+ksNm7Z8Y`}h=W({k|fD|btzPLYz~2#ybe=k z&F)f>U))k3PM$iRL+o8c8jKV3v7^s~YTl0gDDiB3pleblq%W2nYZdFr&gdUjDGb48=k>0M16@ z89`hPh(^;zhR^zzkMGS`n;lr#kNB6NvC2cv`*f>`OONN14dQoA+A7avI39b>Y6q_j zNNhnYBdUt-kPx#oBtSTX?B~=%b%{czJKxFY5F?p;G4FiXy6cV zKQNo!jY0`Uo*@<$=dzoqihyvvp*t5rp5y{ogaw;deeey`W}_zsrMxzA>tk*D^Gi5v>Eg{|LeQ;h98Vtgb*2k%;qBQkb(t|_AYyxN z`dv`TaxQBN)g4sJV7gEUuTo^0_DPz?WR+ z78of6UzDm+&OvONo35B+4ドルIV69rg#MC$bMIx98S%z^`5yQCSAs7vJ%s$cSmLN% ztq>M{YMi4tYF_5SHgI$H%MWnvak?kry6s&i4h_f-QuZ))6LJkn({1GeAPX~;WXgzqY+X-4 zGKRCJ^vuxaIpVYMmlm!8)K8Wi8ドルJn`!}smrhi^+Da?z~xkRkk=OsaieFUgJ zu?Y8!c0=ppiz)qU3O`n|-uqTSC|w%82#ZC4KTbE_r`|DPFDF3?nlq#&igkis7^(S4 zZ(KF}^BC$vu2n-_w0dE4h6-!`r&XxQ`+T56o%8dcA;3wHNZpr?JY9eA@&_Un!KNeY zNUS=GzcA4s;cIY9etK-3)mKr4%~(I4 zQ!vtlh~c;_G^AzdSunX0W;unlv+x+Tq$%{iJn9t_eOjqO5<2{jp14v-&d@tg-f6x; ziPd7qF5+{FiuJ_8CZcD2Z14GM{&+mmccY^JPM?js_Sz5W1YjYO9$SbEx1S}OInL8VZyt3tZ)~jVWu22X!y7`iU&Lb^C&WKcXz%Ag z;HeI#bl-1^x|(!?=jW;vbbfOjIZK_4qH`e5Ac@(yS6U9Z&AWVUBR}aA&5)H2M$?y) zU6Yl90qUm;JUp}M-wy#c6kh}!2QKgfTHuk!L+K9qokC|dt~9L&Z{lceytW3F)F(w` z0y_$sc{!)7bm2TbhX8ErAW4MZ7JE4hJ)O3IdD>lg2*gK{yFJO?HkpUOEk`tAVqYWy zAa0*Kh(fzgiP~0-Rb%2ZPG;`85u62}IMdVCXj11@{-)-b#PmVr?6~Rk5bh@#*7_x;bqm({8Rf;x&zV21<$fkt8|c)< zM}{91M4G+v9%ih(6yY;8*%73{8kb^x=fk$;58?Z6sL&sEtuy1Pv+?T-1v*dgne97! zXY1&=7JpW0|Lmnkylc29ドルUIcCdm6fX!S>ytE^p(3Cg>bEdR_q^Dn}2N|35^?;ppF8;Qy@) zyeiC+@p7ww7H!Oy;h|0Ost@tV%n{vrOn2on)!0u;A+3{Yl(Z|&-KT$oYqo^OpvAP* zU}>`qd8bsZgPb`}JVRqux2vB$d38Byp6!xk|N2Q+e0fOuDWakCK{kG%qjsMnpxX4U z2I>${T3QWv+aJrf`8pnAlfCVsF10lny`^W!*%oO=IC}>tAgzrQhJk=24gf$e;Ec@Y1o!!iuX8oRrh>3p|ap>(|r1{Eu)q)2&_?m}NZl>KoPyT{Z zI4Fo;-Giun^_o`fW zoi&dAVZkQ0xU_Gv??N_%iw0!QUpG=o4_ohRlIi9ijnW=XAaNZ$!uVJu%rKJpaRE7ドル zA2hRTGm?Gvqt@l)gu0#3A4;?^52@K_VgXf!A1h7>o#<;l^>HQvQEl4;PXLz#EmYoQ z)_S~7Nr~O+jfWX~=(tF4@t-x5Z&*LDTc3Otr~a^`QTzSsJf|ox47wYfu!X#1U*7HK z+QDs6ドル!;;h&@r(!ZE}Bdh1(+Bf7Ds@xTp#C+}1)H&oXuC^=#B6rt)k^pPyQn9~G~2 zn6at+2(R5a8sUmw706Fj&R?{p4*XtkDFLPj}}9mQ}2v|cP=L);2nEA*)yqy zi+Fa*%P&;0ptv6guNZf1yZU6#_k%-@UVCpuwE?-W8Zs#v7+YVqi;YgQ(Jgfi2 zq%HFW?U|b>C^32nxLMFgdJ&^`FH4N(c9gzB9>h&3)J$txHNUy<&@phn9vhy?w%==t zw-*b_-01rq%TO*6!O%*10+_=i!$b z?dNY*t{UyDOkeD(4s1Bf)*%!{^JdBxx6~suFnI_V5X1-C~S zud}%mf?oApoe-Ihiqt2c!e*hm@M;y?#7KVPJ%S95vbI#A6CGEV%OvqOL!~xhi#$r2 z$}g5(9W8hi#sYyoU2O3>D3y=&qpHG|Cn2lGlCLxqay!;)Yv19seLfqyzq17ドルOmTRC zinR%w=G~on%`30YlYAb7U!3G&WUoClK0St+EwYZt+P{?YzUM44gmN=2AidAwmw3ドル? z&(^%6Ngqcg(;GxwYvmBy-gq2zzMzlw?h;!Eer% z0ドルEBA0S?v2KaMdC!VMonSCOEXN+@b?#&tUQww$=EsF3()%12KpiOT!ILoJ0$JysR+jDt| zX9lnVF=Tl&LP+N{Z-uEU^LD7u9kp_gP zIu!V4OLylJH`w%RL=x`{+A)p5Qldh2I#PlzA?dW(rg=WwUL3XT!^vH_m2a7I&P_ph zT2$=ES0)+(|GpnZ=U5j)eS8|_H%a$jpL2ZwNL#a|pESOzSXJ#aB;PH>*6@irD2G@y z2M{iyW1~es_|-A%z_VeruJ6Aa*-#5S`c~Q<27ja@ zO>6__rGTAbyjoHVcaL|z_hsG&!nYQYk&J1R>a~wHPAA6;p7@KHYK<_pi76ioj9)3r zvm@np&m7Z|*>|*Go?!0Iy-S7?wP$CTr+aRC2E6z+k$X2UgRA$%<;o$x7q3$a2{)xa zu{g6I(1oVgg5ryI-X1(`;f|0rjqB-XJeNLaB2qgcpuW!_yLnu6Db1+Asn$$UY|D4N zS#`EN5y^n?>OT-&w+46iY&+RQiseT7VvF##FW8btf88&>dAu8@_*{7bho! zRcIq(qnskLCT7jbW@Kk&Ge)O9de^gqq})z9KlGZq2fkWQpP|qZ{%V*Pv2E%5(ZM`! zrpvx_S1~oN4+pQL&rV*hQ%j2+Gzq!G@K`FMM|Ic-!>KYuPaZ-*n%!UZl&#s++BO!v zcj&YUFJRn=x2!muI|AG z_P##WYicJ{UKU z36307)eS*ErQ@)q3$jN3c5zBZ>YP2~A@WJ$seQFbnGqdf9~ApgxvKZ%dZW?P49j18 zIVC|4C>y0;c*xEu->0SFnY|BLL{ZqIzLJ>*C5LpReC?ULm>E|lymCAEx~k}94(zdY zJhKgMQw%BBGGQ&pI_iQT zqjaI-m%oT`;D!6TVs3Hn0k<(e_ymh>f~fcQa&>pf!VzpeXWlk8R1)tLcZA%?Q0nu& zb*%K=gS7XjJT5-@)ZaUoa*}x~`mUYty2XU;P7FbzRbd>*%(|9QTTamLRMdO9qH#HA zBZy<~cobk<9h-fxgvxc9;ed%h=6wwah5r{}{+degroua@;vmj_@(w6oZ z{NrN2+z;*>vDC2`7_X*whSYb7DSI4WtB+RU`F?XxwHroK4FXU)JA|BY^*4UshT; z9&r=-MCE|fnN2T(_bjdmLJqk((^#0H^w%*$#E~+_@+Ct+_S?%O-o*G}Dl9WoEmM z!s)?du4WC1H@Zi+U9dU>?IpeW!S^A;`f9O}?k2-?)El>8LW~&d2N#W>SH1(#(t80r zVZ`BC1S3iF;8_dZD*Jma(>Vo-mAV_jhOBAqg1LpQTffSlY*jYZazQQ?TTZ^EpvULr3 zj`}ct3eS}?!3ドルYpI!6!~C^bfx*n2f54X;iMj9pVnfU}XtuYI$t%^IPV^VN%kl&s85E=<#u&nej6;xf~jb7@prt#?)c`%k)p zS||M>Fn-4jZ`=AR6d7ID!dq`fe|}Dr#{YZ9`)~0cUUzt=+?Z>Sf!)I^NV-UcL6nI3 zzFlNkP0c}(^I$-JHGW`1OZVD4#>`8MZr!S^y)6c4cV7MZ+1g;z*orK7E}g2v_`Vh1 zwg;VHua>IfUUv)8$@gtHqtQ{hbh5(WNvY?BI+qxcjR6ドルaz4M=`TQP!Ky!&Up5!HzG zeLvi0B3I*BV!)DwD?-$n7;X4fw@pp`zjoUxF&n4gE^G!mrgeui#=r44zn>%R`{b;ts-t zSs+rCn29gKT6Dl!BSc##_QdRC8mCGZp7Oo;BAiCC!+cAnlAX;+Io3R>_jFo_uAn#m z4%WC$fdw@+!y`M3_l*C^NHNoa;%gqxBY&(;8&VEpL2JOa-XBkolYP$KR&H=mRvj>| z+?C7GtX4oCLUMf9LIf19EP6-ENR()2WEXeIew?=mVq+=t6)Slty}1?V_X@Iz@qp7t zxPn{L8%+c>cK42(=a7~HR)NmDc1>&}NGxblms9jQPx>Rrz#HHv@U7)n4)R+hNV@o? zlxrBO$P+|LwN5m<&ru<_=%(qtd&6q4ng;#dn-5@te<@%vL`g=BO6oQRg8tbHpKV@%ptxAVH}^C;ydqmiaI5nR8DD?YjEH#u-1PP(SR7 zJDE;Hy|THEA!xP=s^DXLVw;Z>oOI+@r}_ORGG5!LWOG-3*ufdb+MJ-s7ui^4mnil{ zS8%Vtz?t8?Krq7K2hMy^b@Exgxz>L#!}xj`_=%JIgUSQDujxrl5u7Wzl+^?AH^QS; zu=s7q8p6f5wb8txuiUD0Zt1^w6su#m%QF_eZ~AHQ%hO=rMdk_2PQjOJGDM6AI6lYI zJCS_Nmr#8SC)fzffoBlcZ$+%~x+n@yzy6jY=3EWT!gFs(cFc?;I*@ESS|o3RZTpLI zk|@5g=_T>JMe3O<-;$foeptlb*p^ga|of&?@j6#mv^f5+|JaE%31gs1IT zq|kaI9VAaYxiTf){JP=3`h}@2iaWpwG3bwhx$;!i+_*!4S-$!Fb0WPZG4(pf zXM-%GtcvROp_Z-(F;8^tEBMD*$MwG1x>PB=*Wo7865@Aa5ドルal1W2mv(J=7hnxx8W1 zu#VtLibOSgk>bD`$JC6C;cA)vr?dBUt_8emQ6*U9oiOZP;3Hts-KR(a;Ig6PZy zGAm8w%4VCQCpT()O_CpdekFAg4!ONwzT-;Z-rx#a0yCXv~FtR~k9M#;rKVIQB* zC_zFvHYyoLxxJip;Hxg6`XsBef3DngNG^yE|YU=t&BEKH!MU<*jbysn-^}| z1jXB?crVbAuEaqe&R^jJ_FeuBOXfe9-OS+EG2ddVY;CIKJ{fwI`v4jLM&W-J@_9ドルz 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ドルMKs@-(u)4#rVF{f(hma@iTUSxxTRc94<#+q4k@5q;fndlv&ovmftp;m5xst<=day$+i5fvmy^*|iltj`wtbjrlrgb1m=(nip^#1csq4lPJeoj+K913-MC3aD65I ztTUvh;EP*)+?AO12PUU%+IGqsF|24$-b27U5lMv_GV)cRcZl$@;3ocTHV*L(iBwfr zwYp-4_C#%1m5v6;^k3&Ot**VmB4e@RhVRVbCcfL3_qE9)H{4W6X=Z-yvsWFyS2MNF z?v!Xk*Vv&|b{F#KEeB+HC<@`dt%lfrsx33?{sg1q1*j^7g=}2%rr3d*8kd!j=8d>2 zFRIj|Xfkh0TXSZfqCs6<%y!xugt0*mf^3;n5auin?wb&cy25qyqbvpom&zhtuv3rf zdX&47(wmfh@q)bL74ZG&!LKhhrTj+wh@E!_?@}igOoX==Oq1ドルEUMc4D7Y(Um;WQR| zN;h2I4ドルK3Q!JFR3`RO=lyBdx~>W73dgbh2bX=D@y?=s99Rutwqo+P>Qv@K%JMHx0Utte44-lG`mLwmuK=8%frsQ@d4s|CW3w4){#1R!XwNQ^%u3h&Qo1 z6|Z@;F5>F_{Z%Fv12hlvWDFHFuNVIh_TDR~$@Xpc4uVpoJRrRV1O%zlkroi8h)7Yo z5T!^HLa!kxN^b%R51>TpNR!?PQl&`mEs)S_LJ0u^uKPdhn{Vd*W^H^k>s@mbGybEz9L4f@&KC zC&c9?9>0t!?1s$x=M2CudQIY=s^i3Bm;Zw5)P-!|ps6>oHbG*EaeX?rOP%BA#Kx2) zq$cZO%+v^9V|>Bla`nAO&m|SF^N5h2_QaCv+K4bOoC;x%NV$?k7r4>g)Ru}Vfid@m zxs>fpXMSR;O+@}179jii>`6o;PHZC->xNt$QP_lv|hG$?# z&g*ei?mv;L4$Uu%c>oLuYb?>6@RAsXN1GD&@VU#UJrztYS3(d5d)$uI3zzfY837*K zIkyaIgQ11%rfb7b;+KhfO-w6(D^ zy5Tfdw~)6~RJuK*@f(?-OZx_52JUJcLs!_5^%XG$VTaDPeZP_B2zCw8op*bDt9)UD zV>QB#jHW9dLt*=ULxWAvT}n?ab2 znQ5x;bwudEk#_!ETU7(lA8``fva77QY*4j3T4?I#d{i;3BHK9kEyzsc5ZIDBN1yvP z-x>EEFu1=j)Z%7gA3dz%k!BLh22bd*tV~l{o!kbA--hK7u|KEZgK#UztKZ0ドル&b z)?PwVOWFp;uSY;0~xux~RTJ_KQtU!FV-(q@(0ET|7gQh%|_H>r-Bbp}od!G)jx zcg_j_C0ドル^>ixbAI=YHE^&8DAr3i*2HZ0crc*DZIkFOt+8Grger6$GyL{>2!I*EEA& znW?mpFOljt%EmV?vU%)HIZ~w{T=D+>`;L?q!DsY*9X(75x+e?gSK#i)UZ3y#$~ou6 zo?$m1WDXYPFGQGf2;xA@+pDBdxw@-I)(=l9#$*ZxgGmSSg|6WXZEOI`5%C-RhzwiEkZ|MKM zC!GJi>jaDetQ};-t_XoGLcrXULvdJGVFuf8adfazCxy@3YZXuPaERzc-Svdm5$|)~ z_V;^JsfJT+(*-$o=?8kiuVX|uG;b%UueGa^`nY6}MK7sN%OD@B`@C?|ohgsKAANBl z^36dsM5P(yi+{veF3qt;eabZ+_t>6RqmLCSCvW-xyCdVkb9Yw29h@E?psyxR!~(f^ z9@_iJlA$T2pjMT*Ycs-y^%msGIj@95e%zO(QRwux8?m#ejTfiz$q)9=LXdQ7ot$x#p7ljh z>+q&ZvaLh*UE(+ z!ldUdn>VKynK(Du=I~KUAcXei$-#m>dMCw87ドルlE9f4ctnPWV??@V@jGdi@dA=T`|% z{CPCwj3agTAzuU2_jvH=4s>-`2VDRL6&szRrl6LV_PwrkZ5JiZx-~)CJB_Avz2SYY zptZkBewblX{mxHi^BB2#ceB3i`?PGHd3d&%_dWC6EDQ1EcY8EJiEeKXAYY-gJA{DC zT>i`NEe7~o9p__~@YiFQ5x8-Y6|2Z&v%~vkMgh@-Sc;c{kO!0u7R)>f0~oKL!3ISiGl#( zAd(bZWp+cCq_*Oz<5hrz{#+oj72yx(a186y=h)7z9*ra9ox;oq%1vl&iux3|)@4bw zOdl;glG^{rBl$za>tT)DIv|+>A>M&}xKc;$p5dCirrOlUQ&&3LenLApbfI<37k;}a zp{PH?SxHMti}6x@zgJHnb^hrq5-@DihZ?{NGzaSn<0exw^r-2pq*uz=_rg<&&kb(f zviU70Eo(q{#>EB(5Z+adwW#^`@5f@Ge#NuB{&3T>$G0BUBx*(W zcX>O+Z;0$yIXJ#b))gc_vL{p!f8qFB^n>s+hrJj?5_TuhZW1oMf@a)0oFn>=8;#!v zU=kAQ*o4aH0ljehi>`8NmWeg*HQG`Hb2Z!!l@fLDYmg9Mu0#{4CPyd#MTw_sJ&Y$>v(O6U*!jh zx4OvJ+mDQ71x8MRq7#4bMtIqIFg?P5;_`W-~A$x05 z@NlCk(~_qT^jQguv^rN=8SaHdKv?CGw*mv&)%o8)pKJk#N+N&ECX6mv8{YhP2FRb= zb2#!l7#TxGnW8(?xieDHw$y&c6c6_HOj8!i6&U2Y$}Pj$h5+}Ebc&&Tp7ドルN{ zz|4E%XaO*3{(`uB>|`^_eT5i{7RJDPaSC&k-Wpp_fG&`8H3F&Ysl4;u5et2%z^T(2 z=uvQ35ZBrCCC;rx*GfC&z9d<#v=d4rrqm%?f|s7gw99_hzb1?z3gly#c_}8ty5wj$ zb-fwYD%dh43>5RU^D)*cyiY(YD07~HG0=_*z=vN;?8g2H>1g9bE>9*Le2{42^7EySQ$&D3A@m6!Yl<@tx`;*ku$ zARZ4{31!24LEoxT(ZZ!FTJ-_U+Av%u^j;L@=N zIzC_``4d|MFg#k?NP@$(s-}Iu?F%iJ;OQpg#6YZfoT{7GZ5it4H^|HB>EKQm&ZMWr zm@=Zu$^vJ7yM%d%v31~qMnj@?T&vL3w#AY`TC~K5H?N)N&A0Etvh)D(&lJ!cE?yxf zz!X<9+fz5relgoxvh)n_gqm1fvv0su==tz3+(ne)pc$`(1CIy}cyx?k5-qV}Zp{^$G zaqPIo)a9mNXPbhfqZfr1y3qK_sWVz>?=g#aBNz0pP&+ZfU-a zm4VseUBNWBk}Ma2hM8^ZGXX>3LhEEK(C5#JY{ecY2>77yu$eQ832wZBf@)L7j-bNrHaa$?p z16Ahex3LY2ygE_oTb-kx(n+7f^NK-Ok^lxg8?fTkrFIkJ{|*PiaxdK;q3f_%K)W<` z&soR)&RnvuI^QkeROG{N2ET*mp?FWg;fU)v$r5}3Ry`pfJrig109~S2(PkJ9rOsnxqh(*{W;7%r|3~5Oi`#S>daVwL zd_kYWuO$qN#`B$qC4^O7qI;3?yuj|81b+fk=OSwPZQ+o~bzH4hvKMi2F#%wOd+h59 zFF?)O4^xaNG01iaFt!ZY9hLy*G;ik=j<$yebiw?v<)%-e7jsvlweg$=qsstohqk@j zZ6gBI=>uYvel+M@Xf-5Ol@be^SH1x5F0F6UE|}I0aq`1h{*(2pOD z-o4&yP?gCH3u(Z4X^%39zj$hyC2bP6NNXXu^zn~ZJn}0zC zjXNDAA&giOHL-+HLwuJ@Qb%I^^X)O0>Nn|l=N2U$Q}*7Bfi5gC1bZJ|xI3E<|4-eru<@rg{h1d3)u50l;pzdgr0hct z3WST0uK|`fS1^-06XG|J?NrsoFhrgcG{m3sVh1+^Rg5n)TP$HPAEB?Q+f4=}}k)AGq*G3@ypyz`I#kG_zY6H{2dmqQbtbxYhKf?)BJeUy-$TiB!5r(%V7y zSG|Kbyk!_B2*@g@uI9@-Q`TW~I=z+RKYIpZ-rOS>5#VzFbX7xk8o@F^6z)8|V#XyV zt$a1KY{b(orMt1TG$m}^Sl`1M6}UXc+2GRzTK)dp!3<;o#_4~ld<;q>3i@$DKClkT zP{$_IfSis18vlo;@>1t(fWnlM)}oDi)E;(?H|`LkG6*1d%m4wx@5`(IWF)PcBx8OM zlb*fT9+k-4CoCs(yTpIFW+)6yK@iNo?r1)bq;CO-;08LUhOajbU{S0|qEmM%Sv@@m z51l?%#;bnuo`1%{p&GbglFy?U5@wVBtonKcp{jZob{P=Lka8Or5c|4n;)LqB`8_Nb zk{;Mibx-j=J%fOUx`(aeaK7p3ymrg1b=npxW&+}>Xhp(5%a_QR*ouj3mQG91oqUN}SKE=#dp2=^fEY#Vj6HkYqa1EqXCCCg9QT`Jy=N|A3;GH(%8)v4~+=^W?`#*60q^4)bb9xKRNAdG z=yUkahOJ9Uogt92m%vGz&8wKEz#0!TyZhqz(I9gdmrtUpHa1)qHP`wcLm7<#4ngwt zVBJNNAo7G{KW6QoSuVP3|7sfb4!&6NRL(pS!{)6$Hjb+%g@H4+M%o`~mpTgh5fNa4 z4e*C6THJIDoCDixZC!m~FqPoAVFk&!9Ryo@I@=)=xyHQmjyu%t*Um0v_Q|My2IQ`t;RW9q^s`@Xe)2$viVMR{N+@9HOYECvWZgIHx zjDNl{l<~nuygwo0k#mws6=tb~9gylzll#;?uxehv^o%5ドル+y{f~jh%=e@=jywjaddp zoSA83-F=!Y^y>$eLL3ffmYSm8G&q?B;SO+wEJ<%-bjxaq)o2zlbkq?zf#dmi_1i9o z6iu4@0v{P1q$d^?O*hl7o?x@D{S!&U{|H;g)97(&4+^{8Lt@o|G2!NZmbge^3CWbHb}Dk?Y^U6cuR2) zxg&SCjnA)cwXCZexwIF%XM%ZCTVYm6Nn@zi)zH;V+;DJb+^KS$bpM|wKBhVx5cuo1Js-`X)A}=shzh=o;B6u;iwY*u}&k;BhuZ-Z!)j| z%p*xLcKSVGKG_EJ+5iF`7fJ0uqVw2n&6Y0#;#Si$*?|qboATp#o|1_F=V6Ym?yF&7 zF}lNHnDMZpex%*VpgEI9P|!l^TDKjvqF zQr8vCKZ*%-*>d1|@Jp;A1w3{vo6#YT`M=wqdG4|dDIQ7qYor#JE_{QmGZP* zc$;RaE`y&z63ドルX`3S+K#E~BoP9>&mr6O^XPV+#8*->kHC8WEgCx(n1se?gP2`)ll%u`|ucs~DZx89aIMjU>T$g)Ce$ULknUF#zKl-6UUg??1y4A58 z-br2N1Glho@8_*a$S-c>+ctUwY#DWnCNIjqaQ>0lBbmV$s&5)pS49u0_#%7TG|Ahh zu4qa3aDv{mfjd2hyoFxWZVs`F;oo0AXwIRwN%uT?u^fvbap4L(Z10Y|krzYrSh`q6 z>?nsuKGgoquKPQe*Sk^@^y)A%x55hOF(&{N(YqKlyJnFaLarKjyye7gx3pqZE!y%y z-O7R}m^@x@6|XIE;bG{!S3ckdua#o>@H9!eAZt9J^~$w3Q4<%?jw8xg!b785ud(as zVi&%bJt;;No6gN*(SJc@&v&mlNP^8xkz-QP1LCR5IU+xk^%D{T;>S?Utrs`qaACStle-m3Ni7i3c|-1evpxNP;@RH~ z+uj}TQpozO{T2NP{q&uxjDg6wfu&z)?RL;XH;mj0u8OzB?R~{A<^1b#uwrtnrq2vp zEo4v2;mkWPMn`&b$>+za0ドルWA}l=HvHND(x3P}r9`TN9yFr0XE@q$XYljO^&QfIab32?K$Ym(?@ArK! z`**79l9S`=CJg~1gMW&)>~9hx7&w75^n#Bi0gZ)P5jZwMjYx1}A+~~&h*1;hwEA9E zd%mR(&NP0~=Ajsf_oBw{^a%Om^+p;!S@j7Nhf1LLl}8^rA3jE8spB>TKTT}aUomgrv+m4HIH^zc4OKDu zIq_0DXvyR3Zqz94_`3s%yTEp3>UN6@G<1lvv1g_54kb0`ebe>5L$R#cwubyBpOV0G& z73`((Atpkb=~}q$NICvsAtBX-2FlcW0y&axcwC1(D9E;CS%s_U(lSQ(R@%=z?-8l zclH`NdVJ#J&!SbF;al<{jod-&cobeq^da> z?;+>s4DqKRUhmbEP_Zp^43eTn6MMkz#w#{b8!BS?gkMn4^8(A*k(_cN;As3w&}Xcs z$Bx^zsPV8Q2o|O#&dT#RH6=TEO@{# z2RGEt&8vu~+C--UE0W@byusZ!a(`Z<_t?g)?pj(tlx6{fn&0%}d~eg!k|aycmpf7m zj5)AT9>x+_rzRmG&Zo(2?GVH~Al<)q3dgfz4xx%tue53i{<5wq#s7j5hrjd*ba_sx zQ@8Xz#B${iJkaE)d=h|ZKs2lu+n!Dl%(f17!X`fPSX<3mou8alzzrq_xx!mkg;vdo zj`O_W`p6SuYKr{yKW2O%^Jpno4Ee56@qe;M%8Zj_F?81YZBsS#)E?r#lXPA(k|y_b zw?nY^`5fN$E#I;&1VD=@h7&N&@CuOpRCU2umwsH-hh)eZH0pn*|bM^TiC> z!4SiM`wN0fZ<7y=)zxk7`;gg-vahm2_~j_v#zf}@&_j43Za&gD)d@`cMz{G+Y;=au=U>1m`~*3J#0 zdFjB0vvLO)k{-JHnBTLxy8(V^Pbuv{!ZT$xbi?^E5C+5ドルmZ^Obq_lg@X0}m>{QEwK zq2H@;22bZ-_Mfc_QCpYJr0#_FCNnqK^!a2E`zN69Ntx}BVj!^;5ihz~vw45g77KV} z8_DoTATF{Om0q0KQ3jt6W5R$H=~U9|fMPhFSG)h+)UsT#(bw!b*R_8;?n#WK{}$Zf zOU=Y0=mQTrJ_bJ6`K25>VaqtRZ=bwAS^iiR77pTTNoM4ueQ?LKL84EPccY!t=>wdh zV0(_`pi2U5GghlR!{rtgW9;a0Gpqt$!qC#<^gcne5x^bwvm2eq(cjgdd%fq+l$vld zf3~O=;l4PPZMCxJLYj-k0+rdqwmZl4{5byeKEf5oE^dL{7y?V4jQY}v&KpEqUgpnHb#QQ6a@?E2 z(g>Ud?z=_7!XYf?6;VzkPFYfB>joi;=!b=}1x^hZ@P=vc!R19`j zlM|;|-k3sQ2E`?oC&wzzE3P3lF~62}3XAaxEITeZF-+GNsi-`#`5&>+JwOmy4 z`gGU!F;iO<$;x+@e=kz?dybf0b2y}s%s0z5l0+wlx9oe=mavhy_-wmk@1d1xgoj=a zjz%)PC>P{V5Xf6l2;scCTMuP?fgq#28hEjXffY(&e1#(G=SZ}*M032*5M`tv*-5<@ zsoQuOPKJfh&PWzlY~7l%Y6<5%efzcx$lby!;g$=aenq7wfsf&5xeink+%=!eno+1# z`GHBMA@k2aK4wg2+c46&Z%UcVdt!9nE3>{(OUp15!9*j86;@v0K#adX>K^R`tJa!LOf z5Nwjgbe|3C$jCiGi_rcsZBWmp%sowafsXBo)Vmh7m4pziCvLIl3u>n71^QuKj~+df zNWO^TKKkQx?v1jLieHPcdksJ8;s_(PW5<1k7kff>4 z-Og`n80eR*cGlN-B?ePv9|}HC9aMQTc(45)SPC)OZOx|cniikldX?O)joR_uQz#pnH5U@wyG6L`;68Fh{TE3-?eJys0ドルt zwjY?;q9XDjy$cb#8s>Ur(M|ZdOPd8Jxl0Wx`0mZM*;QCmn)cIdRXqFMV`7|DZ8!on zTDR{%K)p~^`3t&zmGKv3`xEdgTtf-$oOE`g4yCq`Cp!#RZ^hOdQdgn|&po(^g@>}F zS6B#r;H`&QP`nyu&Z_x=9!e1l9`#@)1(CY)?zCF zt8D9t#DhVY0SSwm~@LmEI7boZEH+XnE!B?l4x{()G?Tdi7}FCb!T0r=@)q7Kdgg ziQ%5D)S>WNJw9j3X7ApNH&9S!8a6XaZ@d?*VtEK&dX+7P1<5ドルm(jkb2C3mn*or_ZhHLsiX?+)kt6xUOQ-Y%(|v8;jXbvjY8OMJwV6(lD>Nj?Gd zz-dP$%WT0kM5{UdgvUol4#{!0ouioR_r^ThwHb3tR9fN9Me{_KFc&~xHU~%*Nxc8T zNmXZ}y8u-kN2?r>Fu(H9(Cub_@_h44HsAU1w-GQI4acf6h$hNaYJQ{rFNji|HxSZ| zyeV0O;(`+AjqbVNYiDA|^i^D}xSAsyep^fmK}A$}zQ=f&a<)g01%_gt`)x!vml#0b zcA8nG&UXtf)}|HI<2&zbi3(t|c;ssg%?}+gx?jos5<8s4in_lka(kf8#gsx_<%)zw zvBlv4pWK=GEd+I~4a37~og>>JE~@hU$hpulkK`Mc0Zf+JmOPgm1X|qiuQ*g3yIykK39vWH}#NDbcUS&xt$Wm&QoE++B#WKgU%7|a!PFN`(>-lS*BW|mNJE_h z$$P>;Z9=YWieOs#B>KS2Q|-eg7rBfw$Cow;-g%6C%+xTRah zl@gVHy?(7kLn)XNOa{$>@SxldZjqkhIWE71+1qyYTgRAJDhvxvtp#K4a9iT!zqO=%F;2pyTwG3_%H5b z^z8GR?$kg5%Hvp+m>l#Sx+?uWNsWzk>!9Zr+D%;?(ACIxIBjgzhE|F z?<`^ym8q5)(KZlMw0A?rbbTMiAxQYIuEee*={ZK-_O)myyGl0Hr6i
&tbhK;EMYB_b|uw_817ドルlCVt| zs0ut7|0J6Yu!=+xBME3MOZ~6cFbd1Ax!OMw1v&K`joKG{i3h7DGfW;}g@p*lj z04yDc!?R=(In9lD)03KK_a3^)85rGoy()5hCj6-qXu3=NCO$s}FZH@KQf|ML$iHMM#8YLc!vm>a}w9XD4FqsCvlm8eX6`Q?V09xnn*Z zyx%IAY}G578tNK9`tV4>7Q;UAiZRJ{@?;Orb)gJ62zcSIE;NZp%Zj~p!kuY~ZS-Ti z6qoieeL9pfLoIyb*zPc9_y6Y;@lAyp? ze4hz_+hzuR`_5i*qW2&}oi6#JssyHtvL{mr6%Cj7udh=SSo8bMm-wSU$c*O~M|n@% zlj)jdoDQb$GsfoTCAh;@zR^aV&@VL4(t1>}@A!zDZk7A(4G_!-L^dZ+|*&M{sqQLGGEs2TXw68^TF5}K@Q!0Yh zt#p2Z{L$V|S*F*_OgjCY$+tqJVgX}KEd#e3imvozCrDL)CC+*OL`D2(h<=cA`$%Flkd~1GEo`#3$>G(JIjC62L%C`{<%j7hb$w8mubkdvuc>jf)~ zFTaz5@B9^Z>#%t&v9OzB?S$};n=Ip!oVC>f2ci8AO?_O7r2hUk4%+E0B?n|E) zh8Q@w49+?sho*CB6Zn~k?qYH^^R`~huRV`;uznTu>BaK(>rWR+*>oU8j}_X=c7A?w zuAf(|Xv!k#!DjnE8cJ$ZduBVhbixn34Z8av5deku?(yTex>$q7Wdp0IRUwX|+vkxb zOfyyk+#m0J!PoI;(J$+LEE)`?FtvHsiN+aL?A>qS0Rx~Y+Q8(!Obm}&&DZCPyZqt( ze2VK2GM*i|_fn3GP#!QT>wd?+><@xl{iueim_0hq!qxwgur4;ds-fq3dw@cb%cv_p z1&(SKt)Hg3H7BI%Gzcc^W_^fBe&3_{Y`8b<+srqkk|};tqjo%wnfsz{rb#qpl05b4 z9Fp}_`7y=|7D`(}PMN4NfO3ABmA?M6Uzc*P){!URA!i3MaGMot8kp%zyH1O(MU>eqJ3Q}{TpQlAP zQB0dI1yd`Hw*bq?_YRzXQSKqTP_*TOUFgH9n{kSVk8`{vH?|QF7f)&2I1J&+3M7 z!@J2NQvd3~seoLc=- z+FYJa9GMBJ8&T}pu^+AFA?ZkbfFA%Hfvo2Jnonft;#D25so1?UkvWQB?e@#>lb=M* z2^~qT#(W^`{zfJ>Z!S#qRT%+nEfZPaXJZ8ohEZQE9>kwZzWhd|qwx=o3Z@*-G`IeTS z@vZGW5V#&yeNve8ifEI!4Q7Pf1Yy+-Egnt?G*8Gy%c=Z!-_O+(sLSq0uO?blX#t${ z-S=Z})qcc^g%i`U>~Ol}oy#}BD;M3Rt)eI*8~jvmfbRF)WE=+_Do>6VYzVRM|1LIu zAZaoS7J2bNUHEELid*Z?&&o!w=$DkKb|Cu(+K-1)>>KOseBNs5UHZb^$Y{pE$BQwz z=}3oLu9DQ$pPV?sk2Jy z?Gw2QDw}wV7{>vQtb=QT!E~%$l<8#quqz;;j}un9n$un|zevsmhyh4;v4yjfw_~wv zKCsnPj4o-uWZS;N{!CO_Nq80U;5O*Tk9#0)5NPwddaT6ドルL(YE!W6~0E*_CD<@6#@v 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ドルwszDL*wA=x9NtL-)o8a_(`h?og-F53g>dt(d zCB0?c+g#xpkeE#EF%Ro$SMX%o`$G2%15ycX$j~HhFNg3Kn*HZ13_*g4Y$iUZ)^C32 zv_+;8?1`C3UrW8K-Hr329~%T0V(wp%`c&`L5^Lj>z1G?El5d!k`IUAc9m_!{@Y|f= z`MIQvK&xu-ZZ}@~>U0Kpd7ドル+X^T-h=fKS9-4ONih&oFJZ({cj_Zp*071YskTf#lr& zNs4}krwJb%ol(_)Pi-dDZSAX}LE~7he(UW`axW*jkLu&eZ3?2EA@PY~`;7=TopNA6 zabgl?XC=qVg?uld><;57xabg!yy?aq-&zz^@%mti_wxk-y@q(k{=uy3asxx&k}t|s zlrCLL0wP_+MlVt6ARy8L#Dv~E0s_*TNRtkNgbs?*i*yK0N+1z|2ua-Qdp|p~zkB!I z-Fs$t=6U}3&5!|R5;9yl=Q`(nKCk!t4IMT-B6ClqKYa7K_|f)hk<<#%m}^qm;qi4r zPD_flGh4dC@OsNXsAnc1jz11bE3ZYRsF4cz>Qurb2=fo(QqRM7%h+<-fitaeogvd# z-pW_O(J(37@qD6d0m8BC6cY;-+ZM*+OLFQp%Np9=jC9L|BS+pQ-txT)L%j3hs$nF8 z#WP@Bzx6g$a&9b77d{yt+>*{-?D@>hC0(Fwz+vhsY#*wrHU&Cu(_9y~e&k%yQ%IohK>&F)f z9R|bCneIkLqSxUQu-108ドルDu)LHMK!YZ&|$!`*z9@5%aDr@b_%vABYf=8NVE-s)@HW z8YeMgP4G=6B`$uo@YHh)9>|Cvn!M*eJRtl9?fwQ6jWG?JWOffynHEJpwkpSQ1(N6k z=5`K1eu@lk*T=p#er7mQwh$UB6Fl6%*mArhBi(vx+Jlk??gkRHClT@nul4y~JxjX9 zrKFN^!1P)R>3>WYg6^&&=VN|Wpf{AI2sQlVg5NkVgHaMaVC1}8WKCdu?4k(vzGfC{ zDeC^zmX3O(J9KhoEg5c$n86x_P13ドル|F8m@>SDT#P)OGS%U?0bYCy4J09piS?H#=Ms zwFn}KRmjJL`u^$oQlRBSu8u6zmp(ooq2Kh|juxVg6coBe;Y+ImCqPS$DHj9yYyUIt zaX1nNsG072gHMkk-)0JCOvH$FM~(_SM9<$et5klgy8s;%-2l3iq!-pjyir_dby07% zaycjr1DY`a2 z+Fm?$A%h0ib~q6}y77({auskJGMW`zEzR`7udNM6_W31TZSi0naFE(eiqoT4hW-## z<3`t1b@yhp!~lijasfof($xv1itjn(c)huk7j%#qx|4mizn$=xs`qcr*o|v?zmz8g z8QURmZqLgMEi@n?dx=%994Ig$#R4@G0Pp@t5uJQDyXbsshbzCOD_dUPn!{(ZmT&x( z@g3{;*O_N3R-~JFFz(`eq#0ob_b?y%grFEJ*V3-S#yoFfc5iq_y0K%q-s)?mhGDSp zIRm?9E>({`PCRxuCG0Fr{I)pokyNtLU;tDBHXk^!RlFooGd zz3pv^wq6aasTPmH-6rg=Y>{M7_6T11i5?s94DM*r!>V;u!rLcZ?51Fvz@bEjZTXGP zt4Z~@Xl`6Gyjp+ai@63{0rFXBC>Ic%6ドルk|1u=7OfyB`VY*v9Y5-E$Oru181J)$Y)V z>tC7<7_arnmyzb$;tgnv6l#06dx2*b5&o(d@iivi4e~sq;s+OP+4{dUQ)zz4AK#9-j zgA@6l0ZaePmpm$@*V#QJm|)bm%;Az(-yAKUi4r8HZ&?LjZEe!@psCzc5)$-xQ2((| zL^qx!gi51~0s`Vu#&`NZ~TEicYiC34#IOG|$D*XBwM;aS!9}ssh4oMM{eA(%4 zENHtj(|G`}ji7cxNJs~Vlc&=u;_9Z)pMA*^>hqS-*;0aeCQ8)dRO;0A`1@_;#Gn74Vm+q0OoZcj*BYnh-RLU!HJ1J#>(X>-_No<<+(rvs-%){x z6zo;t^-uAYmL0bE&AS6WEq!c-mq*ehWEyi@7)Jwz~Gn~k^m(YM}II1_5>Xgnd^tk#8#kdaI zCWGgznYhh^>2|G}_rl*hpEl!S&rElet-qP3*V_>72IM5`wAc1#)YI&R_;qY;W*~cX zXMEairmODhI;}a0oA&Z^fMmUS@B5ipX@SpbtToT-4kFyR+QPNgUDBlY7R~EIo4a>R zL_7=^j@Zm3k>7#IQ1KU(YVL8yNtS6dObdIl(v^JffRzs0evD>eXx@DrIro@5*pq z=`w<)abzpvpw(0s{o5;kw4cokk(cys&u7nv=#?}tenvlalgbryxzynw&)4y=k7cf! zMn_kLbgV*bt=04b`fawqAUCOy4)(+WC}^Uv6)*1Vnd0Ft*Bg9qrb$U#nB#Tb2K6oT zOYEJ##$)V&y}+z1utDVRxapL~NKr_Pg))s+`>2%UT3>-&`iX}(Fk7k0&JB1M4V&b$ zJ!@q*qg$KqaK^v+QjY4wTp)?Lm>7&)COJ2Uu5Lp@-> z4NQ}fYIxH=`U6^L&Mc|;;XGS8s={W4D2hc2%DQ*`(57we;14qr*hf5_A0e{<0?(Dux{JJc2PB+p1T=E;-Y;)7=G8Mt64it#5@auTUXpzh9+iW*ME#!9go z3HKLl`1e0he{|0+IQmi>^{IFD8im~h2QYM6mVZGv$I$T)iIKKgqi_@q!mTQ7FIiRM z^02A{^X#012Cu;{t9)uA8?yKJfQV~K#~H9k<0ta2ww7+%3qmlwc=tk+))cm`%`_jr zUbi0{6l~ekfLc0!NXA0&6=)}^Q_rWh?q-(K!y=)g%G`!_uPct)2 zVQ-kCC?K^bC=xp_4ayLYdv>-9Ee(DRc?sfAB=g_hRO)A9n&b_dPl7x$-O9inV%^S- z4|Ji<5n~aw6bkszcyz#n`|-zi#z|ibh3kvj^oec?rlxo9b5yg|220-hzze1=b4)nj zHRkofBbFIZ%r1ZeiWR9-fiM~B3;yjIh+~m@~F0MlIB?RPVm!+{h_b5Z#uv3{E*SDH13wO zOL5&xWOzZ&fZjwp;)c6d?wE1k8~*T% zud*at3~orA!Quu;Y}uVx(0gP&U3bb)3d?5$oLxkme|5*f!@yLkQ~N?NbH@)s%w&SH+KgU1%90uSV5@)YcTPK zA7E|7iG_rctnrTB0HF9<qh_PR zLO45E5fdv119`#UtC9X5ドルDo~@fTU50!1S6NPnd0Q2J(nqzFMEITM)5y&;KTmLAb-$ z-}F}0h#K?M*|a#Q;u<;pgfen)ajhl)z8bgnfla4#1ドル}j_wv-@by;xenw0qx`d8vje=md*luu* zttAtmV(|Sl6W9wF#5MfE$S-hq=HZBqe?IsX(YlgkKTbL4Y9lqS>RCz|TN3>ADR=Ge zr&5IjoCy#Vwx#?L`9+1c2H;^X8Rzm2iN&a#px(_p(r!gU)cgcCA zth$;a7mB;+rb6)Gb#}q(_`Z4%a^U%KlPc>Ia8iI@(pC0_1ZJ)kQv>|gaR6}wIAjcD84W<@b@ryykqvm4^q{eg zJS8IXr0`Zdj9(Y5YM!No4%29QL9km#@Hw%8B}u|TKNTTy)sVcON)TP^v0!LYM2V;B zC-!uoE&-6Zxny|jJnuTU{$M$qow9D8O6chj{-i&zF(YiE8&C-4&9>>|2SWGk>OVS5 zv|BpAY~r}IlX$ILAint4KzgU}yM*p*IvNW*_s;1A z>|JV*u15LtC|LJyv0_P@x_R{{;Ej|>tGAZOv1F;A#gubC%@gh8o!w8YTA*!SY_EP;%pk)g zt&O4~3Mld3dyvI2c<)#t=8yo ztfP|8_{w_Fk!Uc?85{|@)KC*=!%ff$^X92xL6{s%oQ5f$?-ofp(NBtS8?Wa`zg%s= z&m0UF`%QPuP1xESTDwc|15Ok@mdlaK@#PJ%@TN}_9Rty8hpKPQrxv*os;R*z(&xPz90gwMz|WE7#!Y*V=SI3Am%q8m8!9_X%6-8k%}8w$nkVw8 zF?y=C3sKJ_H3=$St7Sj@jEc_CQ@-46hw^{h_u&xZ3%HK>@&ZTp|CCG)>|EK~@Clh~ z6>c8=rsa;#rA0;@za7C!-TB=Ww(bU@JB6*wQ54CH0e;y@(%s%avR|4O?`!`M{A0_t zryrMh94+57W+twDoI6uh=}rL8ez2B30ドルzpO|I0P4j=e+hh(_LGU$EhybeIVL_2Jty zx45p0Vu#?jwjxOyo2_%A_H0vGqB5R-_vRW1{GaWsw6J1scb=7Z&rh$kIxBjwH+dy@ z(Fr7g*|$dsA;)K3P+|O1^NX3RjHvxbs|Si7XlFM-9cDH`TEQX8zt{3O3+u}x!?N67 zxEe7lEsC`6Gy@xLQea@ktZS`}aN1FPdA*)My!Ov%2F>#eOuBSsQY(p9~NFE2*P zWKdTx93~=7TS?l)HrpDK&bVses)70CZ4<(^0b~rd0deraf8grz)d2!^7t!fn|bc|y zn+7Go{zw@Stu1+L*Q4`P89o<^BRPMB`fME?2e9C@5ejO*oWp2+6^2m=IDH90q` z(R*`{!GuJd=wHzAh%Eur4-j+2GYvqd7--R0m3ドルX@uUUgP<}6idqxe~zkeqi|GP8^#`i{^!|y6iyf73`v&{E;+}JEEW2evXDK{pvEm)O5{9ctp|n zwYeuiZ#(u_yqW_H5{j?be;a$B<(&nfjff7upooj3hi4qvav2l@*3-(*lm3B%=q;iDl=~rZ)xxCwm#S8@)D%Ie04ドル)?@v(DE3xI@H3=uLS0cHhBo1kGodDJ@2G5E`EB$n65sCe=;+u7wrcsg58vGB(kry)>- zxlPWU+pNjYBN`Mmx;pJ&yZft{j)D62)1B-f;g>(Q=u+VjL%C*Fwcb4&J+t~->*=;B zMw64?CQ3*?Wy2PU@19&=(;htzq-A?(t#jickkz-3xGT;t4^pRc6p-Vh^u=l+6X3cWLi>Cw{G*`u!;WzPC#$=~WQbSSKE3&h(iYrP>c znxZx;_XK|&TlwAb8TYH&es=wg+b^JtYeK2hEy_1_=xMSV_YZ13hu9xBOf;r7?3w+C zr*z7%)Bo_4R!zC(=c{IL>xX!7u^T16kR-~r?klyKK;-^NO-_s5Rleu z0q#w_{9{*{jZ<3u^zrdcsmmwj+m!ktjqk60+z|%qk6$=bdib%6bk)=7dhr*euxh7f zf3cOYGj1B<6llfays}dhvw@^*^peq_W*EIhbXb9ulb5yhhUCW)$blwiHdTLLpj9Iy%=pk zX4CshNl22aMyas$N#UHEOXQWh7-uzZ9E24r2W+M5>P;~TIfCXzU=I|38i_wNV(n5EPaZ5WH#=8Z{4@ki!#rsk z;fkq;cQd})_Rx+eXDc`1re)MVZ3&V4RL);qb4lpQKlgbl=8x@;5f47E6B5qP&~9j; zH#%-PNN94+2#k27@?lV4%y00)>)m=HP&xrV%--c=`pFfToS~L? zYhF}8z5f>^mn@SwIsL}EG<)cc+=fwdao|s|^ew#d(k8<@4xgfy%t_w7ozlm;jq0pd z7Pf<{s-l^_-(*f?v7iqy0+y<2sw5erkt)^iahfac|bc072w)hf1+1mnsh3mkc#zpu zcI#5anH7E`q5!LQ<$a=>gO;WQ%WS8`W@fgyi}(F$Udeb)ZZ!e4C}BAS&@G|(Nase6 zJith$#@y)<%gnfy_plqde7`^2sdzcl`&7&|)g^1rh}cq@owquqt&n;v;ans{){zs( z-Ku%|16~JDJbP=U6zuj^IZZnB<2&7j+%2{6kx<&%u}kg6tn&xe3!cw>nMBf-G-Z3P z@#$N`pE$JSq8n_!8K}O^Ty`*kq$$+o*E|HWF9?{p<9ドルn7b{c`uooil>QXuflX4{Ie z7fo>^YPEVzY$C7QlUpBEeNB0S*IhBK1Ij!i5l}9mw&M}BMue~CfoFdp?yLB_q3a(B zxMlIgFTGM$@QbFeeLX8~mj2~>6@nf(zlH*l2ドルK!vaPV)Sfz8xc;^ZdL#av`0XmFKV zh&0@LbP(K6`%k!O2C-}PD6g z{!%Y>RVv~7mccxBZx{EfzHGujn!0 zr4j3Q=osRt=xW)28~-1BEIN_@heA~ALCooKb^!uxrW{sq<#f)~%(qjt?noqo?p@w9 zYfR7QYioD#lHtXR6*`_Cj+fJTBJ{X5mGe%_l8L5ThSH};=z)Ly?)s%3+EKpf=Fm0bcL^vesDmW$of zClAHPU`s&WXy7mK`4WI6=Q@`j19G{hUBG@tdLL*O$i3EiFfErOI{x)9 z$kZ-yK1v|rW_6bI9l7Crxo{07@%u8K(@j4MgT(Y49p%3%)^+hLSVl7Iex>h+@PyQ^ zyLS#NuQ-(N25>}U-L4(XW z`Q;$EPw#(3Y9a***G!21giR?njW^+0^jnwO-XEF*orxkin*e-72y*r z6^G)CGJ?JZ`7pzRV&-8!Z+1%}!D|SwAInxT|4Wb`x%cm>v zMCQId;d7nq;MfI{O(L&IkjGdX(z`F7kmi?od(VP*+uZL5Y<@ns!g%r7oxz}z&*l3~ zwG6ドルMjLqBFub)wLoQrqnQ2&&iPOXMKoqdDXd~VY~%3dM_YgeY@kyCCGGo6MOSf2Hi z-OkhEQeFFagU@06s5ME{Du3uZ2CpPk#Du)HqIrGdgYjzHw&pkIYIx3bJ>~NL`BI~6 zv;CbmBx5O|HW0R3zWa>8yR_GkvWT{(|NYQvB(B|Y)g!Wl8$-y5Z&dPjW4&h_nB5jJ z&!+$FGKX5-H@eB0TjSOQaFn;yMJH2=2tl5tY?E5jd7@})$|M-W^_(YXF%bk38-y}Y z#$lH_lo8iw1}F@Z!j0oKM;GOWY|Fc+!Jgj5INiHHSpLK)ilmz*C#n0`!v|{SOtGk{ zvpXbR?@5#jQX+L#GCc6Og75t4*@FZ%t;=-rja=dc@%{Mzv6t`lLj-xEs$J0Wv1f1+ zOCug=J1s|{FQWL&%ocS&$$yw#p5MuGYJfiBH0gAqKYs3;lbj}yZ~gU2usURn-OC~| zjwDz_Ow_}pDk^7ZcR&3ao_ifvUud;hRTufThxzI|?P3m5COQk!3ONbm>dJFdvV)%F zN~~H<ZlQ4sFK|;2z>_dvjR{ z;DlnoM`eF7bp7ZSlbvPNj*G0W4;8#OOPKU};#{PmJP%bOdeF8jERc)25 zVl#1Ntp{!2(we2+3KmCizhB!(d{xAlDXe$UNwo1i^Do0KB^dR162wWeB7$dDPRl=f zOraRena3OqmzY7B0-;&}-{XN5Ob~_U6ET@UyI(lER~o{-(b$x-U3hjkMBdM=YyL|5 zpUjVR8tJ0o;vdWAJH95T={d^Q7S{c#n&L0`gc8)bt<7e<2micn!e*n2p@}$^v0cww zbW!pK9y}x^V(u>s7gJ?eoQHk3(TrrS-g^4xlGqsd*gG~kDM%;8Y|W)fArF6eY)Rn6 z3H#t@x^k~KjYC-w)P^y9&jDDf-y-bJ>-&cN^lq}R@zE)Z%y+9I;*ej0x-NpqD>aa* z4n?A@HgTemMBAEhY{cd|_adu--?%lA*Rk|5C% zpRjeWgEPRS5s;IMUT?^gUNm32_y(79y{AvyW0HmIvX&8n(`Kw)3}{te#BW8nYx(i# zm2ATp|#7^Yvb>F!UEXaXQLAV*b60ZjT-s5!-95ドル+hcv4GUn!pn4aqQ zYuJep>NkzF7pelX?D2VxbU6A|G7om7SBWIBGOa8e2>IU_J{;wRt#ibo=t`c>96Qn)#~HN=PGZA>`poyb@&Emtwq|OniJ?fS>6s9hDp5b6S!j zma(l)SWY(_?2(mqudK_8r%!`cN;)3uAH87FxgG?~sJTS!Ia5cNt~5s>saG+~&H?E~ zUIb24LslbYV>XPm!Ot*hpgeJY=%TQwF zis>M{;WvOZ5KcP3kUY`&o!8osE0$USK;@`WA%1H|rt7L^fN|N8gcDPwx<#w^b zk7f^;15N_Lo6>Zn@gr>>$D@Sh{xiH2sK3!!Fn7{eCUHt9V9@$y!BMCxQkDSg`wL3s{(Wn5?T$ECl7{`b>olYbMNbBLakTp z-%*Dq4kw-?sS^**xQO#W1~@p*qB(S8^}|n#h4Dpag^c7y9k+ZlwVp5H87$#4LpM#I zCzIAcf>^}T$#0+>sA(uHv>(=J6hv|@CUTLSCO0O-)60v{P777x?R6zdhpIo0^W&q` zslMV~yc?y%Fh%TpyCwqtOezk|4wWR`CT!LcLLWCz%X=^&Fi%FYS;JEjwyv+C zJm|J7e$IS@Uqoma2tXAYwkEPSaP~l>z>ol6@#y{RtO`9ecnVwPpL+T$Yh55|e`1TL z`NGTr%XuXrR?yEWkFWh!4au7T>7?hAeRO3jykXbv{x8B>m@~!j2mIzEjazTp+*P@P z{#d@Vg=Ty}GQ39b?!zbjVi!a zz4I@q!8Fda4}ME&vpfn4bc6hDHe*9JEIJnJ>AN7-ko%!{wCVi-T$J)v7$QFrsz`#T|DFZS#1+Q<{c z)}R%xXJUwqwUJ&DOfS&o5DC4me6CA@_SJ?UNZb3xE4yc90`OqRIS zbqbF|uRi+;g&3MJ%gnmW_2;;~K39A7Er8mi(aOu zu?3AU1#8>3O}ntY4-ocY1hk zi%`yit5A*qx>lLkCMZ47VF}Y1z0nB?D$ihXE(R7l>O{ufN47h>N z6F^3w=7W3jw=^S_87YRalr%Yph=DX&dkpF^+pJ1zcuJGRv8TbG8;1@nqx71$-!;M4zvWsmjt;=n=*k5PTz3-%O)tPH!*DNJ8yO+SVu7)x@=#G>Hn+^D2x}tTjShcbM4EYwwr;5Pe6wK8fJ?R^1?vV)YYyE!d`=Yn(YncPcn4u0%7Jge8CScFWdCD|2sLpiFg0 z;f=aS=FWlRVOQF3t^ptm(W7(DzGOd{Ha*i#D%?9>+x&{G_l$(9%D&%)&O`RNd-K5p z{etB4L_NIgYE37G&VtCf>Kl1Jy2O&ILeFp+bx z9w{&aeq2esy>^}8kwEhFt9CM-L*>3u{cLK?eQm;@kKjYUIb@D0}bc!-odv zU)+Fu5Olg~5-|7&c~SuE!+fm`@Q%SSRV)&v?x!eiOl?gLp64@oXi7H}{qoj1-1Cb) zAescK6Lc4xerK5$;{c%}K9>-+HZsGPMYx5ドルT)0%+toYF)GM#HEsh~LfRW0h~%<}xb5r8d8yk~iizuo`?6q`pybnaqntpcve>VVE}+P>-XIPJpM{6cSA9%imT z2CE+ZN)%bjJXDCB4_NXovlyHmi7{V@yoF`^HHJ)T(^_*-I@?8wtEo z|MHvx)(dG#&VsTd>Q`!F4=4+2 zr#pK7_{h6MLtz3j9;~1l%6W&eGNKE4uB5Ol;TgPJ402fAt)Nu$nhK{R4Uk7^;tfA065-D*k#tLzuv{%}=_u zh5EpGt+vsO^5?Bp^tGHf94F~P^!!104QRmEp?fb7`Ctffer+3|IN_|M=lJt!W!83ドル z9TGpKtq@E+-YHI1M{idRC9&P|R>`$?F+MhI+A%Q(?Cht}XUZgn)D@tbkw-<6zmh`b zu2wW>Y3+7a`cwPLYGm!3R)__WLuyuPO$Qh43F|}8EgQGug}+Hdh?=C^1q*2&VEsO8 zscIp}uH=bmN-G_o{^fGWXUYgvm0aZwfuOsif$UzcPm4`CjzZH*Y7=(GwH*qOVIi zsNIHAs6~@zhy3lSQi7lxLR6`p?8Gl;yr_{Z#ewhiSaiP#VJi-)Vvo&(5F_@xRBu-= zIGdO%B#N@N+|v5hR?qo}JY|fI=tv<~q?8*#`k4xnj*ze=?zws8u6#b^!s4~>8w|=O zIi+8H??27alYm|{`MI6EQE`hQceey#vV5#d&cwCL<12a;b7g=4*xmk*rrxuk!cd`i zM*_O*i>h(I3~C>5+J3YZ1VJv7o)R_Cc%!wMy~9GHBGxbANRi+e)A_k+ilpZs=pmo} zuG~{p?w+xJlls$HT0NSlGrQJ{m7LS{=GG#ajNNkXt%9#wy103NF`}%9?&t(`qX^Cv zpMk|hqgY)qj7TuPdf7Z@**aP9Q+wN#TiAtYkMN`ycG_PaN%IKt{les{ zG`mcsce2P;?|y9`rw%@k+1wVCU^5ap3tpg=n7^G59!La2Rs{eJ2B!^)=_6h$c)~EU z56;+A zI;0kmOV$|7*Y|zY6~TuSdhRa#rVwjSBT2WW6W75=Szc~bL1-Uh?FYg-nC1|g=8c5& zImc`nW>ZfmCD?lzGgvbJN4TIx52ye)hZ8Rt4IwBG4Gmz+AE*DGq zV8H9EfFESC`8q5=|6(Plvx4{Xg>{D@=)gbO-}ce}n*EJ>Mwx}+>tL(3z>Spn1U(DG zr~BK;oN*p+<&gpxp}^1fwtby)zzp{-9g2js^d^yoy#51&xwmggngoi*olnenrp&yz zpLsE}c9*8_UL|nieOjLkoDRiop^v}kTgBBmw)Ld(Qyp9ghE!bo@^*o4iwyhF8_iju=P}1cI5&Mb1Xx$LLl$M!rt?%M%&kUZ(LyJ#-08WHUhBoHk0ドルH70^20*C*}^l^>{% z9B~=%yGkfumN~24nV3mZA39-6Elr5WfELXY&i8YaHwwo%=7D}H&iKNa zk1ABGy-Y)7+!{WMjz4M5EJ=D5FOsgX?)J1YY~P;o*K%*(Z1&py)-!q3SgtAo9Wg}G zC&tRBb>tK{j~s8-je7I6Xr)!P#`?WIU~s#6fhu)f*yPSvknCTO!)L{{(qyknBn=T( zP7-OGg7Rv)xk+pQt`|oeQeVAIQ27;Kr~51^MTXB*yvu+_3^XByrx!vAyGnQ#*BX7bP#5~UxJuysF9E}AE$&yl>joc0kC@U|1C@&13edjv#| z|6%+1|K>6w`N7~tRot)X z^Mbbr7rv(^fVpZ4UAukk++fF{qx&K8Sxw3E9eO+X`a#c~mz;_BU7Kkra&534_$ao& zCb(mlFmWV@qINOm%mcgq-u)JvbH#tpj`3Y6s~yvQgb6hbgDn@ZtRo;nZxLRAby54Z zSzRAy{&M#gAaIZc_Y-=!7KAzwi8=XdwsAHiTt9O#SxHYGk6m;=aRTH&o;m*!I{bf< z08#x<`kn6y_`k>5e|Mae6iWpWrSGG6jRp>w2c|z`+eMCp&dqes z-T(Ztb?nH}G9{3fCwN$eMSU%6ZwRPAWdzoIHd`A2D433Ev{%bW?1v?e8ImmF&H@MJ zdkcqY&@YUA%K|-QA14&_8eots#NK;fO^eXr4PmtVzm@hOFhB*2`}<0(q4ckygx)c* z?3{Rw!_%b2xvh(lw(*_F`~XG_f_Fx&LeCOGf#WZ39vfR9XKVq@>(le~@}FJx@JsP% ztOV+p1nk~8ZsXIZ)|_rFn#))Hg_095z0a>_?WC43tgJ2=jWFS+d38a43(nQf>_?DY zyt`5;k#3fy%&X-?>*L#rIWLE(-2$j_W$&ug}(ayfc$MfLR#6eX; z34^a6zX4@`vtQ5NLt*KzAQN}+(;q6nsgdAra8w@MZwMVp4v*g30L=K01Hh5L=PkdZ zHjjJmrEEP2krG{bTh@?e@?Ks4G{WH*)Xc=_uVS zl$xARIZt{xV}~E;N#u80x<2(hct3ak{^yt-<6!qg#bp`py_jh~cs%s1bb&v{6^e=y z<)4kmrolnu^d+$(wkz5t$c`s{arp72ilc`&h+&<8lwgp6kb1xnhf`w^cjt#ecsf(| zvLj*diH?T4KQzkqULUs#v(A6e6b+l_Uujj*c`7ynpj-J+0b=;dHj1A(qyLYWHc54i zsU8+v-7f6s>WoP8zf6wJ?l&{bBpM5(lyoz0Xn?*EJphDHlBiZgtQnZ*SH`%BXpc4u zH;w^cJ{8di622VH`^FNGFVFSg>pXGiN)8b#nfT|O;0#DT!c0%@Mf@`001u~f;fJ(N zOC9CB+W76fnkClyVy!7cY>e5Ndu_qi=kdm-x^5>dkwQ%@`mi`ckepx5h=Gck6MOpS z+Q*5{6(<|a6(=rniy3dq=-j#z$zuv5zv1nd>>+>T*QeqN`>}QA*oWprO3?NGfl4}g zSz8bzE$bsrfa9a#=PaG`8J=%34ドルf?oZH|%d+^1pJ0O(OL4atNECrBFn?BFH#=nx)n zqfF=e)81Py^PpAyGB*D(ohk0Qwbka7@i8Lcy^wj}puvO;{D4%OQoXvycmG6JI$F{j z17293y`9DO*56Ar>4zy*%W5!RMc}a!5mJb}NQA6{FZC4taHd?fzSbvSk*!o@`l(%a zXwWW`O|DBQMLn(;kLY(bSkoD3fr56ドルtC%pJo*8A_NbhU-*|o*0jfAT%D`MPsEVi#i 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ドルmWtprP@5#fwL|Bpq+2+dSQR9z=tmPqJ^{xo9f4`*U#PtEe>Dw zIa;G^b|(~5?tRDd)S|r|B@PZPiE;B;h-NDH_0WdqS?57JLB{bPGMU??IHdxV%QMI_ zHX7E<9ilmnbo5ke5nxi_2$zop3k5>X0o|_uq1)R9TLn$lCQ;!x_a(=#J8a+ob0h1S zcUeCim)Z}S8q0u^;YnZM!LpYr1*mQU^d~hmJYk=VXUMq)4BlllonPqBJ^qhG%_U)|z!6lbI@9QKBp`%-xpq-?z zgAALaGLZZ?exaFr&H`3_d4Ee^5wfaqyJ3GFn}4NxOPp?vGKPN3deIc0?L+s*G>HCh zJp46=;~zTz0z0ZKeu|I!n79iB-z2FfYg%#D*1K|aSj3T4>J3y&vbshs1`ct{HxwQ; z(g|f2IfE0eROf8adMm1SR1ikmcfryCt@tDGW>uuf(k6<|19l>fp{IQR&j>@AT*RbVtVswkWeDstTEDwb(uYKh)w{;SjQPqHOc!>xU zmycDg{%8p$&pLgqeC}w*;hnBtNqt))SKZq}@F&<<=1ylzdzsz!e1wge zNg$THwkz0WBi;K5Uzk($p72t+@Yk-x9}z{n?b|sSCO7#xr^TXQyGCa}__qD^5OfjM z8>8r=rvB!o_J|{0fQ&Vj_8u^tOhgpRzp4=?7?u}UY%HBQv9e~8-+M}}Rj=yqrhl)6 zc`rs>pOJd`v%V_Qlr|2;MpoPJ^mwGI78#o>Y8FYK5%|MJ-Hv@0c<8if+$gxqpgfiq zxmZ#w`4h>pw7mlGcI%p^o_kk3^42TNeEh*>bbk2sPj(L<$nt6d^xzjz8qqich4kbk zO2G1c7ドル-km8(7R2khaVx3QrEvM=(-VN7VSm`g$F5LL=ZBO?<0 z#PtNEaMeKdn9oL5#Xv~8`Kbn_Gv-gOagWxLM&Ew8y~r=m`1Ek_h!PBeI-&b>trC4V zx}Qa2XuJY*3Gcr>mI&Q+=Wqzy_7@&j|3rs!7{Ox&fC7-|0j5iW?YHm^OmYv)LbKu& z@0!|t9k03Yp7XNC)8O4j-;7w?&7-% zO_IC*`3dDKuX2gNx_i3vn(V{Q#%>`uVF#I$M|kv-4|6ドル?vWKrmeVqTBIgqRit6tv8 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ドル$FJR%gwwv=H~d9a3dZmUWN#b6usLx_psyh;~FKEE{gn-wBdQf&I$R$^5ICI(tjae z9^l8(X4bjj_`FPyuGX0%^33o2VHb}08rRkOjwqX#g4qtQE)HSh!pzHz0K23d7Cyk`zYT_GL&G8eL5}{qCoYwg6Ol@k5y< zh=T?u5W?{=DCn6rn*ptM^f!$a%e>C5ドル|;;xmnZz<8u?oijc8h1w}a`_u7(p{xq0zy zlyzB=Y`{`3t%#v*R_V!!j?t`ZE^~*#4qPO9a^BRB^%Z}Rc*?e?K`ni-b!wl4I9Mn> zb6P>fYwW8VHUXFF)K^&^H6^24N0qinB58ry)>!Al;2YDli>S{~*2gL?Z7tb@Bw*Ge zS02JSi6NwV9`Krn-7z%ow8{B{3e5Q3j>iD{?-gfdK`VaJI5cB%$*bx2%tp?gzk|n0hVW?ug(_eix zj>#Gluk<#vziduw)jnef&i_kx?8|>}vHw+E416Di6`+%t7`QT$_+CCVwQ3a?72IDt zJNy(m)VAxi?{tPpnV6v|Bd<;q>DwY4zI^?f%-xt(^hP80JK|e6u2b#rT+pG%an)-C z1g}8upcKY{MxE*({&%>#|6d>b--(O=Kg}flcl~|{^Ou*N@FuRDfMQoCshN^imtIaK z4%aD5%P+U5bbs$Vk(|zuMnba%HckGYt>yn+FVp|&^WrieL5WGIfEJDT z&#jSr9Q6m3clZAk%S&X?S6jsu$@udjVKe^Q&VFw)_ZH|g9+><8jw}+;=Cvjdmx*fM-Kco;M|M4n>Bl?ASP1Cbw2T>~? z95RwPLS9?YRQ7NH%t@*E+&a8}Doz3uTt4syr_hmTA2TOn?0a!rN?VC<-`e+m&%lz= zNoVA>lWt_hhMxS5Ie)B29siPCdxe9S01UUFbtUK%8ew~lRp0ev!8qpC3xyFG>%176 z3~dR^)3oZ+w}62>@u#O+6J5z9^IGrePa*hER+b%Wu2+!HF1*%F=X?A)A>>x^M>nM8 zpJMXThm(f0#ION4V37ドル?U0bs}f;+Xud4A+hiqRL=g1tkvBK*KrF67XyS_E#Ojd^7q zqU%rb1Su2TO%**-NOj_2ye?-zw(QqiyC%2hYQ8FVoHKkU!xf#daP`fz1?fxGM6SFI`ao z%~7brL`@JPqvhd5oQpt1Utv5y`)Hxl;KNOoYQ0J4r$aq5JHm?zjIEclmu z)hdX#eesno93wep`G2d_F&>$CS(2J?N8eRkeU`r0ドルFUxt2i#XBZ3l>>Kp2fj5v?$$ z(xi$SBA;GvJ0Fe;%UfXfJM_k*owZNe6ZaZ7=!qTBL}k2x!%Ae_?nNK=@^G|wL0FOU z^iU^i&-c=>&bKK2?UNT+&rc@g9AaWJ)vO9()Fm8_M{}`eA zoA9z!FyK#+P%Qkm%{K`3Orm`Uak~$e)+0q4=;NQvBQXyy*caIQY3&fN`O5YsejEsY zn6T8zEHtG#K$Qe%oizD)M)u^5z8+%v0r5CmbL_xoK%ZyYpEFMF$LAZLt6OIz<-eki zLWDO10@9>!K^D9fk0yGd^Lt5T%ihEcDN)+p?G3Ks~ z0t2kx=(tFWcn{OX)iUPll%;*And~lOvSVub+0QG z^|QY!z6xLXLEgzosrPv3mzlmSc&P&Bekg#v4|tI#K+Re`bOgq2wdvzFJ=~5@N8wwX z9{f<2u)pmi4;vji5&b@gJsq6Ver z#UyeO=RG zB=63L4zn5U`iLA?b^8a`_xiOQ-;Bh(*(&*Eg?WzxM!+tOt-E6P97W5s2QsT-k%LLswJG`jHx6VYiC4$?q_yw$JXXtIP7CX! z`}Pa7EK06DdH-8+IdgFtpHavh^SBftIJl-7?i@pWd)}gpNB8E1-fbplx1(ywB>UGWv{{$%#vvzF zpIDT=k;!6PTJY|B=x3b0!?3W-DQ%LK2P%yXZo2Q%}uc^}d5cfR59BA1=B z3`>$WIjYMfE11E=?l&B87NG7b7`EM%DT1)x_y6S^G%vcW6My>p2g~Tq#}_y*mIPdt zek)v?g4M_R?V}xubH{r}kVH+i)e7MHLqf?-nryLaJm-Im)EA&-;?jQk&;8cyXI^bG8e;g+hmr=v`fLrCOylGTP) z6io*4>XC)RV25Vm$#kp1v*fZg9Y$*AwpV#W)3$BiRCUQ9=YZ@=X*XmQO=Jly2pcH#nt zNG5|&VU0S_sFdkttG)zrtEg(z=evrGr?MuenX7|?o}Q3@P_s-Q2^)ML1EdlJ$rlVWiz2MzL|3mZNqCO&0QHj_sG+5P&$zJ zxU-F)%4pUzSa)bj5iZGCHp6zM$?S;3!hJbX%MJge@M0zuO%bY>5!L{j)*oQHji>dtkFI0wi0#B|-79esOgtz^>A; zco&QTdQzzHVCr6ドルXBK?i*=5VDuTPS!8^XVd=0&?s;U);9#Bvg5#8GOK#=ZJ?Wfq=#K*xNaAX>#fxO~&I9bkrqA=WeihN(Co{Hc$g5SB8Sw z6ZO+zY=Jzv0l>qCGg*-rK|Yc)`@j{CBn?IE8OI%gzsrs%iDoTHS-RuX*ULrjBaa@?G7+zBBhoP7x04?c+)t+Qeg0MO*)4#6+Xa_rp5Iu&o~Cl;c<2)tzewz9?b75}guq@refd2ltb#j$vfxdyl>P*{ z|9E4f;nLYrx0NWB;H%Ikkl|{zZ{kKV0ドルmQ9rV3X9VOGTErP*(tU-FmU7Lm22Y#;iB zyV-Hro?bG8zY4JQNj00ドル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ドルhSu__d;rjN(Uxbm_bKTKNj6a5$Y; z@F&%kH)8Z}1w}Ai6)TIyZoI=bcCATd>8tvf;9Jvvx%~{OVX$s3(&;pB>pkL?EME&c z^U>|%#}eMkAm)79r(=}lNjcX0#DhE}qCB5SJTd?u6;x>ne(mWdZIL(OACKVYvj-nG zB|!{?jl-m)|0>r4f_)MSovm1sc4E`M)6VokfovVGzSK~Q}9rbsrEzZ&E=DtS@RLt+2)tY4m!d9ou3p17z7mSpPTVL4}=F# zGqZz^U;>yk`l5(B{HI?%M%WaMs#WE$!-vZLl8CVAtmmB#m&Fy29LRPjHPo{p=SXFO z>~vDC0>e8Ymhr!g`&kdAUU=b33)vf%AK+F_pEvFm{Du=1%_|(mREJC=Qv23;Nbw!^ zh}P@%^BZYfE-yyL#z_@#emE=@7I&o zm}4dnZNnGFTbhpy)RW%wHl?=;yM1TNqqvYWPu{^?d@^}=*Be{+P5jBWN_%gycADu| z(Df_T<7u44-(-cf-zfPV%ZajfBCq%MYAMM0Pz9@RDu5&df$h5YJvO`I75KO`-YG?4Sw9&wQPrl zic;==y9$r}sU`|#I4hJjsrY>&A|k?6y16<1q35|pqvrd=dk@b?|7*tflr#js0epct zK1E|7%)^%$OI~j32K-6Vh6$JCySkclBgE}&6k2badp}oDZB<#{np&p-@26ドル(kg+6w z=dnpABSk414l77FkXi{*wVG|3a7bu26D?^~=f62vXlranJ2Eb5JK(Q##dWcF8;{kEeA#9Q<=+h zGXPUbn}T!FR96t5W&}_XD?8ogQ2j#$S-NK;o{z;9r(CUcbP2mNDM-&>aF8~C2-?wY zltAf!qgk#o_tqGop-2Ogn3H89ep%=8(CqpRtYrII%CixkKc&u8sd~p=ckFe=qR*fX z%?k2hW$n9&a&AE&BFsv*xhbHlY;K890QO*-`3U=nkBIIQ?lR$=M}DW83fz2MIA9$m zRzy9nTUN#S-iNvRr;HZUBYA4+e~CPvJ6vB9v07ZVqVPf8g4+hR>T)fEpSKMMPu=L0 zxovUg+Ihv{o%=aa=kKL)U)zY$xyAeud^G!0^KJT7DFRQXPPm(YZGk>A%LcjR&(*h$ zPgP2?RWd(hrn}cf_pgNGuP{-4R)pZ@VeDOS56YeU{l~MlYp8_Dt$la1{baQdxw;o{ zmWabx999z~dPPeJ0Qk+iG!d$kHVFjf2D%{*t)IIzHBbt3JZ?UUNN?WicMsi7UcD#| zYNM11*Oj7lQInV^8?XoxUj;mDff{H$iv7WWP{GaVeGZYKgCM!qw)SUjEP=;!Etj0r znME@fpj;?1KoPGR^9!4Zg*+*5@?|hd9dBug6QeV8cX!DR3zaQg%ypN2`P}RcWCF72 zLiQtujliS8<20z&3segnjawd@smd?akz;rmwbwh}fg#pcvx_kk&nh9t=;y4zhgebj zzu#141-8jDKw~waZQC@z=Q3N?5?=ky?6Z7=tDTf{-2M|kVM`W0qd=Mfs6COSYJINl zIz!9`@vJ1O{Kk@>ihHbi%J6V#vqRa%D~7>R;i*SzlC_t&E95%CfT9sC5&1ojTG}|4 zMKyQL_s&wWNJ91Aa76OK9q=W>C({_!XHdrA{Y&@_B(+BhvHLHa47A18Ct3AP#pEC3 zdQN-UH>6vVFTKgUi@7x$|AO7we6KC8-fZ>$#LJ&rijV$fm?+_uZ_-~E3#wavT{bad zeHC6PKBiP^J)?t8gVv#f$m=A*emDex z^sVV*dhHK##8aj!e~{}Pn^Jutc{1kW!+bL731h-SVnIIN4n=80Z~>a^4=oYZOsr>m zm`&5HYE6jFlPg*|0uvKj>x}KDhT`dyGdGGhrccqvCC+1p)_H!T6$xRPx;6r@%G}K% z{GNecS|G~Au5?qmX0^nk#HCbd;kzT!<2`b$+glcm+~n(v_ovod_g%}`i^p4oraw=7 zFUoYq2=jk!^^!DQvc7+so#PpoQRJ)tTKFK@H?g9iK&NiM01uB_hjd*FEJirs`Rhr7 zX@1IXOJc{`NiOxXa(jlx_BPgxe9qUnQcTv3d$`+9VvuJ7iC7SF;+RVBG6vx|$;hw= zb9cVUe9@H2ii*(5Go5o{kl4cU8-H7EN~@p)T)?qT`mLIbZZZNTf$N}kHyI^KH0jlf z8UFkI+!4}L`pD*X(WhvZ-Lk5ドルYU2ZpesHidOL`mCwj?8@^#T^DO2GUG+YxCB_fw8+rC` ziAdefDZEPO+b0tRi2&rm7-x@OIGGNtLw-HK0^HqTPMO+UC)$uxfjpAGRXef!C6Gwy zb{f~SWNwTA{CF9>$Zjv?^Hm-^PO3F5qTg7U12fuaLdXXNc>U-NXp|ESe#-l=lpPL? zPqV#N&ic59z;p3ssqrZTI=AyClCfWS@cNLGXe2D0-~*9B%}D6Z(=-vWH*@5hGi|d+ zKkt`X8V-~We-hfRY;2I&1tsipS98ClWlR?sK4itng)^nom+RB5m;4y*c6(K5{Qhe_Z9D{4JrOF1l62&ta)q~ceH9k_{<@%l{>`g z29;0AZ1>QeS^ydTe|L?5?h0&fWzE(a^611ドルnGuZPD&6&u$E6Mw(A$l*IS zp@Ff_S=sI}eD%lKY?e{^AeO+;dnz~Jh8JfTI7VHJy!NYLnYHFHM6^oz5>sxVEcKbg z^|iZ9tWr#)y?*pytDsR6L@KifG5knY5<4dmijo|`+jzs0h{ff-kjk(?)gpv$n0q{5 za!a`c_bJbmQMla=kA>g-*UqG|br_xkmq3Xi?*a~+4p0W8jRJA|HJ>G4rs8nyZKJDa zn{sp$?+9{CozI!P$E%o0Jl-oKEn5PqB>9mwZ6Nj0X4RAsAmz`o^uVI5He1H#bm6-r z=Vm);?uy{NJCni3mZ#}Zp%XPU(6Ne*b_QJk%~9hto=(7rIQ(;&;(ch?vrrwfD!6x~ z=Kg$s98uiXtnw+>_T`!B({yYnsV8~A;W&0UQIHH4dlY|8yVV_owQY;cfxwk_qIP&Y z^Ocjg%f}@xtL1c}W)rS1oA*x=vECDyrFYP%)^+hcXYgwqTxQ{BRuG3V*YY+weyonl zE2aywYKeL`$aS;+jGnDUB1ETX{3qk<`5@jla8ei2zgoaouf-w^5c-@|cpkc>z9l+r zj)0(RJi1wR1kDCuZB0Y!M1Wn>S&dF1lfq!#S-Wbtk3L6AYW0K9p*c@IWEemu2UY^% zKVY_5sCWxhV^DR@Be0JC4L%YK-6YOwrmy&(W#-Xa;Gl#!1a&`L;Q!%p4ghI z$!=jxu_kd^nYKQpxz)~t(Zf()sOEbic}<2@?8io|d?_psoz zZR~k@rJ$nc)?|{_>vJmsK^Lz5C2wAvKKPvq<8kyna9;5mgaik{nzxcl@ej|qh#sys z<+@nve2;jq^~npc&5`}n6b)c`5z*x72r4;m$u-@v_ct~mvu)7ujg;kGX8qPT%R{-mS%)de1iv`ULZ}yy%mbQBN}mCvD}vK zQg@QTN)%Ls_o|8mx&`F2Hwx~bCLP_Ir(P}w1uAS*4HAD7x05G)F*h&h5#1S<18m48 zGqwcD(QqaG1HQ;&ycKAoZPJf}#r--C_kH4^6QNLaQ_yq2*!D#Wo$y)XfGg9?xkz@f zZs7(^dqpI`WY;>Qa*Z3M2g3$Z*!s}XrC>kHUzZt~wnQ0=FMR7BZ#(3o>Je4rn!AGs zQG(M-O@(&{8%q8beyV2WYkdy(4?d35htd^U1zFuO+w-J*m!k0Bz8L=FV*BRb8$A54 z4!ZxNbNr8g?Eid>{zv2Y@9;m!f4o`$e{diE3ドルErX;a>XRIS0r;|B?Fq?~LES!?BQm Gmi`OP9<6%- literal 0 HcmV?d00001 diff --git a/questions/question_012.md b/questions/question_012.md new file mode 100644 index 0000000..4390e1e --- /dev/null +++ b/questions/question_012.md @@ -0,0 +1,36 @@ +| 第12讲答疑 问题列表 | +|--------------| +|爬虫能采集视频并储存吗| +|headers是必须加的吗?| +|为什么大部分正则表达式只能匹配英文,怎样才能最规范完整的匹配中文?| +|有没有可能实现根据不同情况用不同匹配的爬虫| +|utf-8和gbk编码区别在哪儿| +|想知道为什么那个豆瓣的网址会转义两次?转义两次之后就定位到其他页面了嘛?| +|!rm在Windows下是什么,在哪里找有关其他的语句?| +|在那个正则里面,名称可以单独显示,价格也可以单独显示,但是两个放在一起用[/S/s]*?下面的list不能显示两个一起怎么弄| +|爬虫是什么网站都能抓吗,会不会有什么网站有保护机制(有密码)之类的,如果这样,要怎么办呢| +|老师我们的网址不一样,名称那个网址有好几个标红的斜杠,全都需要用反斜杠来纠正吗吗| +|对于排行榜是动态的情况,爬虫怎样能采得信息呢?另外,动态排行榜是一种什么样的排行榜呢?| +|Python的框架除了构建网站还能干啥?| +|请问在很多网站别人都有防止爬虫的操作,当别人防止爬虫的操作我们不能破解的时候,这时候还能用什么去读取别人的数据呀?| +|如果网页内容中不全是有规律性的 该怎么捕获?
期末考试的考核方式| +|那个pattern的顺序是不是就是说,你给crawl提供pattern ,然后通过下面的info = self.extract(content,pattern)把pattern传给extract| +|Terminal页面单机右键没有refresh是浏览器问题吗?要每次重开?| +|Python就是爬虫的最优选择吗| +|在MyCrawler类进行初始化时,不能像你写的那样在定义类时直接初始化,MyCrawler不接受任何参数,只能单独调用_init_进行初始化,这是为什么呢| +|cat不是内部或外部命令也不是可运行的程序或批处理文件请问是什么意思,怎么解决| +|将网页拖到底部会自动往下加载新的数据,或者有加载更多这样的按钮,这样的网页怎么采集数据| +|后期的bilibili和豆瓣的数据爬取是在原来类的基础上操作吗?封装的类那里运行了吗?| +|老师您好,在找百度翻译的URL的时候发现有好多URL,该怎么有效找到有功能的URL呢| +|网页中的视频和图片可以趴下了吗?| +|想问下后面是都学爬虫吗?还有在第0课中为什么我的jupyter notebook中打不开terminal?| +|bilibili网页源码搜索"跃入人海"是从哪搜索的| +|爬虫有法律风险嘛?| +|为啥要尝试加¦来防止乱码| +|b站排行榜中"综合评分"在源码中没有直接显示,要如何抓取呢| +|如果网站是要求帐号密码那要怎样爬取?| +|正则表达式的应用,转化不太懂| +|按定义说别的语言都可以设计爬虫吗| +|不加cookies好像有些网站进不去,比如百度,好像不是是否登录的问题,进入首页后,会随机分配一个cookies。| +|如何学会设计框架?一款框架的设计是否和其业务联系十分紧密?是否框架的本质在于一类业务间的高度重复性?是否源于Web开发本身类型单一,所以能出现像Flask,Django这样的通用型框架?| +|碰到需要登录或者动态验证的网站怎么办?| \ No newline at end of file From 83999953610795e718d5ea59879dca65c8ba8b8e Mon Sep 17 00:00:00 2001 From: Guang Chen Date: 2020年5月22日 20:34:43 +0800 Subject: [PATCH 03/13] QA 12 added --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fee8d39..8fba01c 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ | - | 网络爬虫第0课:浏览器背后干的那些事儿
摘要:了解、开发爬虫必须了解的HTTP/HTML知识,从输入网址到看见网页,浏览器背地里干的那些事儿。 | [L11.2](https://www.bilibili.com/video/av92186118?p=28) | | - | 第11讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_011.md))
摘要:爬虫有什么"高级"应用、什么样的网站是"软柿子"、正向最大匹配能用吗、pyquery与jQuery、爬虫难吗、图片影片怎么爬、玩转正则需要记住吗、网站反爬有哪些手段、爬网页要遵守的规定、递归过程中最小值的定义、网站是不是都能爬、requests的header部分是做什么的、百度网分享链接和分析密码的爬取策略、正则表达式如何匹配"所有符号"、get和post的区别、爬虫与数据可视化、爬虫翻页链接的处理、学爬虫有什么好课程、对课上的"干货"力不从心怎么办、有没有可能不分析页面源码也能做抽取、反爬常用手段、验证码问题怎么解决等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=29) | | 2020年5月22日 | 第12讲:爬虫框架初步设计与B站豆瓣初步尝试
摘要:构建爬虫基础类(框架),了解框架、脚手架和库的差别,复习类的设计和构建,对B站和豆瓣的排行榜进行采集,构建完整的信息抽取用正则表达式,熟悉RegexBuilder等正则调试工具的使用,用copy as Curl->requests技巧"克隆"浏览器的访问请求。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_12.ipynb)
![第十二课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_12_001.jpg)| [L12.1](https://www.bilibili.com/video/av92186118?p=30) | +| - | 第12讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_012.md))
摘要:爬虫能采集视频吗、headers是否必须、正则能否匹配中文、根据不同情况采用不同匹配的爬虫、UTF-8和GBK的区别、课上豆瓣的网址为什么会被加长转义、windows命令行常用命令哪里找、爬虫是什么网站都能抓吗、有密码保护之类手段保护的网址如何怕取、正则里的反斜杠都要转义吗、动态排行榜怎么采集、Python框架除了构建网站还能干啥、有防爬虫无法破解的网站数据怎么获取、页面内容缺少规律性怎么配置、Terminal页面右键没有refresh选项怎么办、Python是爬虫的最佳选择吗、网页拖到下面自动加载或点击更多加载的页面怎么抓取、类似百度翻译的页面怎么找到目标url、爬虫是否有法律风险、什么样的业务适合开发框架等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=31) | 学习资源推荐: 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) From 2e08f3f32e207cfe0ce6866beddb33a1abb0175a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年5月28日 20:20:13 +0800 Subject: [PATCH 04/13] class 13 added --- README.md | 3 +- code/Python_Class_13.ipynb | 561 +++++++++++++++++++++++++++++++++++++ 2 files changed, 563 insertions(+), 1 deletion(-) create mode 100644 code/Python_Class_13.ipynb diff --git a/README.md b/README.md index 8fba01c..8fc468b 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,8 @@ | - | 网络爬虫第0课:浏览器背后干的那些事儿
摘要:了解、开发爬虫必须了解的HTTP/HTML知识,从输入网址到看见网页,浏览器背地里干的那些事儿。 | [L11.2](https://www.bilibili.com/video/av92186118?p=28) | | - | 第11讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_011.md))
摘要:爬虫有什么"高级"应用、什么样的网站是"软柿子"、正向最大匹配能用吗、pyquery与jQuery、爬虫难吗、图片影片怎么爬、玩转正则需要记住吗、网站反爬有哪些手段、爬网页要遵守的规定、递归过程中最小值的定义、网站是不是都能爬、requests的header部分是做什么的、百度网分享链接和分析密码的爬取策略、正则表达式如何匹配"所有符号"、get和post的区别、爬虫与数据可视化、爬虫翻页链接的处理、学爬虫有什么好课程、对课上的"干货"力不从心怎么办、有没有可能不分析页面源码也能做抽取、反爬常用手段、验证码问题怎么解决等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=29) | | 2020年5月22日 | 第12讲:爬虫框架初步设计与B站豆瓣初步尝试
摘要:构建爬虫基础类(框架),了解框架、脚手架和库的差别,复习类的设计和构建,对B站和豆瓣的排行榜进行采集,构建完整的信息抽取用正则表达式,熟悉RegexBuilder等正则调试工具的使用,用copy as Curl->requests技巧"克隆"浏览器的访问请求。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_12.ipynb)
![第十二课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_12_001.jpg)| [L12.1](https://www.bilibili.com/video/av92186118?p=30) | -| - | 第12讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_012.md))
摘要:爬虫能采集视频吗、headers是否必须、正则能否匹配中文、根据不同情况采用不同匹配的爬虫、UTF-8和GBK的区别、课上豆瓣的网址为什么会被加长转义、windows命令行常用命令哪里找、爬虫是什么网站都能抓吗、有密码保护之类手段保护的网址如何怕取、正则里的反斜杠都要转义吗、动态排行榜怎么采集、Python框架除了构建网站还能干啥、有防爬虫无法破解的网站数据怎么获取、页面内容缺少规律性怎么配置、Terminal页面右键没有refresh选项怎么办、Python是爬虫的最佳选择吗、网页拖到下面自动加载或点击更多加载的页面怎么抓取、类似百度翻译的页面怎么找到目标url、爬虫是否有法律风险、什么样的业务适合开发框架等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=31) | +| - | 第12讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_012.md))
摘要:爬虫能采集视频吗、headers是否必须、正则能否匹配中文、根据不同情况采用不同匹配的爬虫、UTF-8和GBK的区别、课上豆瓣的网址为什么会被加长转义、windows命令行常用命令哪里找、爬虫是什么网站都能抓吗、有密码保护之类手段保护的网址如何怕取、正则里的反斜杠都要转义吗、动态排行榜怎么采集、Python框架除了构建网站还能干啥、有防爬虫无法破解的网站数据怎么获取、页面内容缺少规律性怎么配置、Terminal页面右键没有refresh选项怎么办、Python是爬虫的最佳选择吗、网页拖到下面自动加载或点击更多加载的页面怎么抓取、类似百度翻译的页面怎么找到目标url、爬虫是否有法律风险、什么样的业务适合开发框架等。 | [L12.2](https://www.bilibili.com/video/av92186118?p=31) | +| - | 第13讲:豆瓣爬虫的进化与爬虫基类的完善
摘要:构建豆瓣图书网页单页的完整爬虫,重点解决信息抽取正则表达式的配置和缺失信息项的处理,完善爬虫基类中headers的设置,通过继承机制构建豆瓣图书页面爬虫类。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_13.ipynb) | [L13.1](https://www.bilibili.com/video/av92186118?p=32) | 学习资源推荐: 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) diff --git a/code/Python_Class_13.ipynb b/code/Python_Class_13.ipynb new file mode 100644 index 0000000..76b73c2 --- /dev/null +++ b/code/Python_Class_13.ipynb @@ -0,0 +1,561 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 基础爬虫类(框架)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[1;31mDocstring:\u001b[0m\n", + "D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n", + "If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n", + "If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n", + "In either case, this is followed by: for k in F: D[k] = F[k]\n", + "\u001b[1;31mType:\u001b[0m method_descriptor\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dict.update?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 对豆瓣进行测试" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler = MyCrawler('douban_book.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "b_crawler.crawl(\n", + " 'https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C',\n", + " 'src=\"(.*?\\d+.jpg)\"[\\S\\s]*?\\s*(.*?)\\s*<\\/div>[\\S\\s]*?
\\s*([\\S\\s]*?)\\s*<\\/div>',\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "class MyDoubanCrawler(MyCrawler):\n", + " def extract(self, content, pattern_main, pattern_star):\n", + " result = re.findall(pattern_main, content)\n", + " for index in range(len(result)):\n", + "# for book_info in result:\n", + " if 'allstar' in result[index][4]:\n", + " items = re.findall(pattern_star, result[index][4])\n", + " else:\n", + " items = [['0', '0', '0']]\n", + " result[index] = list(result[index])\n", + " del result[index][4]\n", + " result[index].extend(items[0])\n", + "# print(result[index])\n", + " return result\n", + " \n", + " def crawl(self, url, pattern_main, pattern_star, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern_main, pattern_star)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "b_douban_crawler = MyDoubanCrawler('douban_book_new.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "b_douban_crawler.crawl(\n", + " 'https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C',\n", + " 'src=\"(.*?\\d+.jpg)\"[\\S\\s]*?\\s*(.*?)\\s*<\\/div>[\\S\\s]*?
\\s*([\\S\\s]*?)\\s*<\\/div>',\n", + " 'allstar(\\d+)\"[\\S\\s]*?rating_nums\">([^<]*?)<\\/span>[\\S\\s]*?\\((\\d+)'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://img1.doubanio.com/view/subject/s/public/s33631858.jpg|||https://book.douban.com/subject/35044046/|||绁炵粡缃戠粶涓庢繁搴〉�〈範|||閭遍敗楣� / 鏈烘�板伐涓氬嚭鐗堢ぞ / 2020年4月10日 / 149.00鍏億||45|||9.3|||149\n", + "https://img9.doubanio.com/view/subject/s/public/s29738046.jpg|||https://book.douban.com/subject/30192800/|||Python绁炵粡缃戠粶缂栫▼|||[鑻盷濉旈噷鍏嬄锋媺甯屽痉锛圱ariq Rashid锛� / 鏋楄祼 / 浜烘皯閭�鐢靛嚭鐗堢ぞ / 2018-4 / 69.00鍏億||45|||9.2|||453\n", + "https://img1.doubanio.com/view/subject/s/public/s29839337.jpg|||https://book.douban.com/subject/30293801/|||Python娣卞害瀛〈範|||[缇嶿 寮楁湕绱(三)摝鈥(四)倴鑾� / 寮犱寒 / 浜烘皯閭�鐢靛嚭鐗堢ぞ / 2018-8 / 119.00鍏億||50|||9.5|||570\n", + "https://img9.doubanio.com/view/subject/s/public/s29815955.jpg|||https://book.douban.com/subject/30270959/|||娣卞害瀛〈範鍏ラ棬|||[ 鏃ワ冀 鏂嬭棨搴锋瘏 / 闄嗗畤鏉� / 浜烘皯閭�鐢靛嚭鐗堢ぞ / 2018-7 / 59.00鍏億||45|||9.4|||506\n", + "https://img1.doubanio.com/view/subject/s/public/s32295077.jpg|||https://book.douban.com/subject/33414479/|||娣卞害瀛〈範鐨勬暟瀛�|||[鏃�]娑屼簳鑹�骞搞�乕鏃�]娑屼簳璐炵編 / 鏉ㄧ憺榫� / 浜烘皯閭�鐢靛嚭鐗堢ぞ / 2019-4 / 69.00鍏億||45|||9.0|||111\n", + "https://img1.doubanio.com/view/subject/s/public/s33557648.jpg|||https://book.douban.com/subject/34941715/|||鏁板瓧鎬濈淮|||[钁�] 闃挎灄澶氣�(一)ゥ鍒╃淮鎷� / 鑳′′皬閿� / 涓�淇′′嚭鐗堢ぞ / 2020年1月1日 / 69.00|||45|||8.6|||12\n", + "https://img9.doubanio.com/view/subject/s/public/s33545334.jpg|||https://book.douban.com/subject/34927262/|||娣卞叆娴呭嚭鍥剧�炵粡缃戠粶锛欸NN鍘熺悊瑙f瀽|||鍒樺繝闆ㄣ��鏉庡溅闇栥��鍛ㄦ磱銆�钁� / 鏈烘�板伐涓氬嚭鐗堢ぞ / 2019年12月25日 / 89鍏億||25|||5.2|||38\n", + "https://img9.doubanio.com/view/subject/s/public/s28855545.jpg|||https://book.douban.com/subject/26727997/|||Neural Networks and Deep Learning|||Michael Nielsen / 2016-1|||45|||9.4|||202\n", + "https://img1.doubanio.com/view/subject/s/public/s29936638.jpg|||https://book.douban.com/subject/30236893/|||绁炵粡缃戠粶璁捐�★紙鍘熶功绗�2鐗堬級|||Martin T. Hagan銆丠oward B. Demuth銆丮ark H. Beale / 绔犳瘏 / 鏈烘�板伐涓氬嚭鐗堢ぞ / 2017-11 / 99.00鍏億||45|||8.8|||15\n", + "https://img3.doubanio.com/view/subject/s/public/s4410591.jpg|||https://book.douban.com/subject/4146246/|||绁炵粡缃戠粶鍦ㄥ簲鐢ㄧ�戝�〉拰宸ョ▼涓�鐨勫簲鐢▅||钀ㄩ┈鎷夎緵鑽� / 2010-1 / 88.00鍏億||0|||0|||0\n", + "https://img3.doubanio.com/view/subject/s/public/s29249951.jpg|||https://book.douban.com/subject/26945232/|||Make Your Own Neural Network|||Tariq Rashid / CreateSpace Independent Publishing Platform / 2016年3月31日 / USD 45.00|||50|||9.6|||54\n", + "https://img9.doubanio.com/view/subject/s/public/s29877486.jpg|||https://book.douban.com/subject/30333961/|||鍥捐В娣卞害瀛〈範涓庣�炵粡缃戠粶锛氫粠寮犻噺鍒癟ensorFlow瀹炵幇|||寮犲钩 / 鐢靛瓙宸ヤ笟鍑虹増绀� / 2018-10 / 79.00鍏億||0|||0|||0\n", + "https://img3.doubanio.com/view/subject/s/public/s28070570.jpg|||https://book.douban.com/subject/26388161/|||MATLAB绁炵粡缃戠粶43涓�妗堜緥鍒嗘瀽|||鐜嬪皬宸濄�佸彶宄般�侀儊纾娿�佹潕娲� / 鍖椾含鑸�绌鸿埅澶╁ぇ瀛〉嚭鐗堢ぞ / 2013年8月1日 / CNY 48.00|||45|||8.5|||18\n", + "https://img3.doubanio.com/view/subject/s/public/s3898822.jpg|||https://book.douban.com/subject/2584657/|||Neural Networks and Learning Machines|||Simon O. Haykin / Pearson / 2008年11月28日 / USD 252.40|||45|||8.7|||53\n", + "https://img9.doubanio.com/view/subject/s/public/s1695376.jpg|||https://book.douban.com/subject/1138922/|||绁炵粡缃戠粶鍘熺悊(鍘熶功绗�2鐗�)|||Simon Haykin / 鍙朵笘浼熴�佸彶蹇犳�� / 鏈烘�板伐涓氬嚭鐗堢ぞ / 2004-1 / 69.00鍏億||35|||7.3|||54\n", + "https://img9.doubanio.com/view/subject/s/public/s28342396.jpg|||https://book.douban.com/subject/26666358/|||杩炴帴缁勶細閫犲氨鐙�涓�鏃犱簩鐨勪綘|||[缇嶿 鎵跨幇宄� / 瀛欏ぉ榻� / 娓呭崕澶у�〉嚭鐗堢ぞ / 2016-1 / 45|||45|||8.5|||285\n", + "https://img1.doubanio.com/view/subject/s/public/s6458908.jpg|||https://book.douban.com/subject/3890040/|||绁炵粡缃戠粶鎺у埗|||寰愪附濞� / 2009-7 / 28.00鍏億||0|||0|||0\n", + "https://img1.doubanio.com/view/subject/s/public/s28107307.jpg|||https://book.douban.com/subject/26422529/|||Neural Networks and Statistical Learning|||Ke-Lin Du銆丮. N. S. Swamy / Springer / 2013年12月7日 / USD 129.00|||0|||0|||0\n", + "https://img9.doubanio.com/view/subject/s/public/s1663944.jpg|||https://book.douban.com/subject/1159821/|||鎰忚瘑鐨勫畤瀹檤||[缇嶿 鏉版媺灏斿痉路鍩冨痉灏旀浖銆乕缇嶿 鏈卞埄娆�路鎵樿�哄凹 / 椤惧嚒鍙� / 涓婃捣绉戝�《妧鏈�鍑虹増绀� / 2004-1 / 27.00鍏億||40|||8.3|||192\n", + "https://img1.doubanio.com/view/subject/s/public/s6517517.jpg|||https://book.douban.com/subject/6529821/|||Unsupervised Learning|||A Bradford Book / 1999年6月11日 / USD 40.00|||0|||0|||0\n" + ] + } + ], + "source": [ + "!cat douban_book_new.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "a = [1,2,3]" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "del a[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[1].extend" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://img1.doubanio.com/view/subject/s/public/s33631858.jpg|||https://book.douban.com/subject/35044046/|||神经网络与深度学习|||邱锡鹏 / 机械工业出版社 / 2020年4月10日 / 149.00元|||\n", + " 9.3\n", + "\n", + " \n", + " (149人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s29738046.jpg|||https://book.douban.com/subject/30192800/|||Python神经网络编程|||[英]塔里克·拉希德(Tariq Rashid) / 林赐 / 人民邮电出版社 / 2018-4 / 69.00元|||\n", + " 9.2\n", + "\n", + " \n", + " (452人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s29839337.jpg|||https://book.douban.com/subject/30293801/|||Python深度学习|||[美] 弗朗索瓦•肖莱 / 张亮 / 人民邮电出版社 / 2018-8 / 119.00元|||\n", + " 9.5\n", + "\n", + " \n", + " (570人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s29815955.jpg|||https://book.douban.com/subject/30270959/|||深度学习入门|||[ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元|||\n", + " 9.4\n", + "\n", + " \n", + " (506人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s32295077.jpg|||https://book.douban.com/subject/33414479/|||深度学习的数学|||[日]涌井良幸、[日]涌井贞美 / 杨瑞龙 / 人民邮电出版社 / 2019-4 / 69.00元|||\n", + " 9.0\n", + "\n", + " \n", + " (111人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s33557648.jpg|||https://book.douban.com/subject/34941715/|||数字思维|||[葡] 阿林多•奥利维拉 / 胡小锐 / 中信出版社 / 2020年1月1日 / 69.00|||\n", + " 8.6\n", + "\n", + " \n", + " (12人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s33545334.jpg|||https://book.douban.com/subject/34927262/|||深入浅出图神经网络:GNN原理解析|||刘忠雨 李彦霖 周洋 著 / 机械工业出版社 / 2019年12月25日 / 89元|||\n", + " 5.2\n", + "\n", + " \n", + " (38人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s28855545.jpg|||https://book.douban.com/subject/26727997/|||Neural Networks and Deep Learning|||Michael Nielsen / 2016-1|||\n", + " 9.4\n", + "\n", + " \n", + " (202人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s29936638.jpg|||https://book.douban.com/subject/30236893/|||神经网络设计(原书第2版)|||Martin T. Hagan、Howard B. Demuth、Mark H. Beale / 章毅 / 机械工业出版社 / 2017-11 / 99.00元|||\n", + " 8.8\n", + "\n", + " \n", + " (15人评价)\n", + " \n", + "https://img3.doubanio.com/view/subject/s/public/s4410591.jpg|||https://book.douban.com/subject/4146246/|||神经网络在应用科学和工程中的应用|||萨马拉辛荷 / 2010-1 / 88.00元|||\n", + " (少于10人评价)\n", + " \n", + "https://img3.doubanio.com/view/subject/s/public/s29249951.jpg|||https://book.douban.com/subject/26945232/|||Make Your Own Neural Network|||Tariq Rashid / CreateSpace Independent Publishing Platform / 2016年3月31日 / USD 45.00|||\n", + " 9.6\n", + "\n", + " \n", + " (54人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s29877486.jpg|||https://book.douban.com/subject/30333961/|||图解深度学习与神经网络:从张量到TensorFlow实现|||张平 / 电子工业出版社 / 2018-10 / 79.00元|||\n", + " (少于10人评价)\n", + " \n", + "https://img3.doubanio.com/view/subject/s/public/s28070570.jpg|||https://book.douban.com/subject/26388161/|||MATLAB神经网络43个案例分析|||王小川、史峰、郁磊、李洋 / 北京航空航天大学出版社 / 2013年8月1日 / CNY 48.00|||\n", + " 8.5\n", + "\n", + " \n", + " (18人评价)\n", + " \n", + "https://img3.doubanio.com/view/subject/s/public/s3898822.jpg|||https://book.douban.com/subject/2584657/|||Neural Networks and Learning Machines|||Simon O. Haykin / Pearson / 2008年11月28日 / USD 252.40|||\n", + " 8.7\n", + "\n", + " \n", + " (53人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s1695376.jpg|||https://book.douban.com/subject/1138922/|||神经网络原理(原书第2版)|||Simon Haykin / 叶世伟、史忠植 / 机械工业出版社 / 2004-1 / 69.00元|||\n", + " 7.3\n", + "\n", + " \n", + " (54人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s28342396.jpg|||https://book.douban.com/subject/26666358/|||连接组:造就独一无二的你|||[美] 承现峻 / 孙天齐 / 清华大学出版社 / 2016-1 / 45|||\n", + " 8.5\n", + "\n", + " \n", + " (285人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s6458908.jpg|||https://book.douban.com/subject/3890040/|||神经网络控制|||徐丽娜 / 2009-7 / 28.00元|||\n", + " (少于10人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s28107307.jpg|||https://book.douban.com/subject/26422529/|||Neural Networks and Statistical Learning|||Ke-Lin Du、M. N. S. Swamy / Springer / 2013年12月7日 / USD 129.00|||\n", + " (少于10人评价)\n", + " \n", + "https://img9.doubanio.com/view/subject/s/public/s1663944.jpg|||https://book.douban.com/subject/1159821/|||意识的宇宙|||[美] 杰拉尔德·埃德尔曼、[美] 朱利欧·托诺尼 / 顾凡及 / 上海科学技术出版社 / 2004-1 / 27.00元|||\n", + " 8.3\n", + "\n", + " \n", + " (192人评价)\n", + " \n", + "https://img1.doubanio.com/view/subject/s/public/s6517517.jpg|||https://book.douban.com/subject/6529821/|||Unsupervised Learning|||A Bradford Book / 1999年6月11日 / USD 40.00|||\n", + " (少于10人评价)\n", + " \n", + "\n" + ] + } + ], + "source": [ + "with open('douban_book.txt', encoding='utf-8') as f:\n", + " print(f.read())" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "\n", + "\n", + "headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + "}\n", + "\n", + "response = requests.get('https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C', headers=headers)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "48038" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(response.text)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "assert('Neural Networks and Deep Learning' in response.text)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('https://img1.doubanio.com/view/subject/s/public/s33631858.jpg',\n", + " 'https://book.douban.com/subject/35044046/',\n", + " '神经网络与深度学习',\n", + " '邱锡鹏 / 机械工业出版社 / 2020年4月10日 / 149.00元',\n", + " '\\n 9.3\\n\\n \\n (149人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s29738046.jpg',\n", + " 'https://book.douban.com/subject/30192800/',\n", + " 'Python神经网络编程',\n", + " '[英]塔里克·拉希德(Tariq Rashid) / 林赐 / 人民邮电出版社 / 2018-4 / 69.00元',\n", + " '\\n 9.2\\n\\n \\n (450人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s29839337.jpg',\n", + " 'https://book.douban.com/subject/30293801/',\n", + " 'Python深度学习',\n", + " '[美] 弗朗索瓦•肖莱 / 张亮 / 人民邮电出版社 / 2018-8 / 119.00元',\n", + " '\\n 9.5\\n\\n \\n (569人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s29815955.jpg',\n", + " 'https://book.douban.com/subject/30270959/',\n", + " '深度学习入门',\n", + " '[ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元',\n", + " '\\n 9.4\\n\\n \\n (505人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s32295077.jpg',\n", + " 'https://book.douban.com/subject/33414479/',\n", + " '深度学习的数学',\n", + " '[日]涌井良幸、[日]涌井贞美 / 杨瑞龙 / 人民邮电出版社 / 2019-4 / 69.00元',\n", + " '\\n 9.0\\n\\n \\n (110人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s33557648.jpg',\n", + " 'https://book.douban.com/subject/34941715/',\n", + " '数字思维',\n", + " '[葡] 阿林多•奥利维拉 / 胡小锐 / 中信出版社 / 2020年1月1日 / 69.00',\n", + " '\\n 8.6\\n\\n \\n (12人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s33545334.jpg',\n", + " 'https://book.douban.com/subject/34927262/',\n", + " '深入浅出图神经网络:GNN原理解析',\n", + " '刘忠雨\\u3000李彦霖\\u3000周洋\\u3000著 / 机械工业出版社 / 2019年12月25日 / 89元',\n", + " '\\n 5.2\\n\\n \\n (38人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s28855545.jpg',\n", + " 'https://book.douban.com/subject/26727997/',\n", + " 'Neural Networks and Deep Learning',\n", + " 'Michael Nielsen / 2016-1',\n", + " '\\n 9.4\\n\\n \\n (202人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s29936638.jpg',\n", + " 'https://book.douban.com/subject/30236893/',\n", + " '神经网络设计(原书第2版)',\n", + " 'Martin T. Hagan、Howard B. Demuth、Mark H. Beale / 章毅 / 机械工业出版社 / 2017-11 / 99.00元',\n", + " '\\n 8.8\\n\\n \\n (15人评价)\\n '),\n", + " ('https://img3.doubanio.com/view/subject/s/public/s4410591.jpg',\n", + " 'https://book.douban.com/subject/4146246/',\n", + " '神经网络在应用科学和工程中的应用',\n", + " '萨马拉辛荷 / 2010-1 / 88.00元',\n", + " '\\n (少于10人评价)\\n '),\n", + " ('https://img3.doubanio.com/view/subject/s/public/s29249951.jpg',\n", + " 'https://book.douban.com/subject/26945232/',\n", + " 'Make Your Own Neural Network',\n", + " 'Tariq Rashid / CreateSpace Independent Publishing Platform / 2016年3月31日 / USD 45.00',\n", + " '\\n 9.6\\n\\n \\n (54人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s29877486.jpg',\n", + " 'https://book.douban.com/subject/30333961/',\n", + " '图解深度学习与神经网络:从张量到TensorFlow实现',\n", + " '张平 / 电子工业出版社 / 2018-10 / 79.00元',\n", + " '\\n (少于10人评价)\\n '),\n", + " ('https://img3.doubanio.com/view/subject/s/public/s28070570.jpg',\n", + " 'https://book.douban.com/subject/26388161/',\n", + " 'MATLAB神经网络43个案例分析',\n", + " '王小川、史峰、郁磊、李洋 / 北京航空航天大学出版社 / 2013年8月1日 / CNY 48.00',\n", + " '\\n 8.5\\n\\n \\n (18人评价)\\n '),\n", + " ('https://img3.doubanio.com/view/subject/s/public/s3898822.jpg',\n", + " 'https://book.douban.com/subject/2584657/',\n", + " 'Neural Networks and Learning Machines',\n", + " 'Simon O. Haykin / Pearson / 2008年11月28日 / USD 252.40',\n", + " '\\n 8.7\\n\\n \\n (53人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s1695376.jpg',\n", + " 'https://book.douban.com/subject/1138922/',\n", + " '神经网络原理(原书第2版)',\n", + " 'Simon Haykin / 叶世伟、史忠植 / 机械工业出版社 / 2004-1 / 69.00元',\n", + " '\\n 7.3\\n\\n \\n (54人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s28342396.jpg',\n", + " 'https://book.douban.com/subject/26666358/',\n", + " '连接组:造就独一无二的你',\n", + " '[美] 承现峻 / 孙天齐 / 清华大学出版社 / 2016-1 / 45',\n", + " '\\n 8.5\\n\\n \\n (285人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s6458908.jpg',\n", + " 'https://book.douban.com/subject/3890040/',\n", + " '神经网络控制',\n", + " '徐丽娜 / 2009-7 / 28.00元',\n", + " '\\n (少于10人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s28107307.jpg',\n", + " 'https://book.douban.com/subject/26422529/',\n", + " 'Neural Networks and Statistical Learning',\n", + " 'Ke-Lin Du、M. N. S. Swamy / Springer / 2013年12月7日 / USD 129.00',\n", + " '\\n (少于10人评价)\\n '),\n", + " ('https://img9.doubanio.com/view/subject/s/public/s1663944.jpg',\n", + " 'https://book.douban.com/subject/1159821/',\n", + " '意识的宇宙',\n", + " '[美] 杰拉尔德·埃德尔曼、[美] 朱利欧·托诺尼 / 顾凡及 / 上海科学技术出版社 / 2004-1 / 27.00元',\n", + " '\\n 8.3\\n\\n \\n (192人评价)\\n '),\n", + " ('https://img1.doubanio.com/view/subject/s/public/s6517517.jpg',\n", + " 'https://book.douban.com/subject/6529821/',\n", + " 'Unsupervised Learning',\n", + " 'A Bradford Book / 1999年6月11日 / USD 40.00',\n", + " '\\n (少于10人评价)\\n ')]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "re.findall(\n", + " 'src=\"(.*?\\d+.jpg)\"[\\S\\s]*?\\s*(.*?)\\s*<\\/div>[\\S\\s]*?
\\s*([\\S\\s]*?)\\s*<\\/div>',\n", + " response.text\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From b47d675d448106f8ab7aa926c7f9ee3c26c62fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年5月30日 21:48:27 +0800 Subject: [PATCH 05/13] QA 13 added --- README.md | 4 ++-- questions/question_013.md | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 questions/question_013.md diff --git a/README.md b/README.md index 8fc468b..ee6c510 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ | - | 第11讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_011.md))
摘要:爬虫有什么"高级"应用、什么样的网站是"软柿子"、正向最大匹配能用吗、pyquery与jQuery、爬虫难吗、图片影片怎么爬、玩转正则需要记住吗、网站反爬有哪些手段、爬网页要遵守的规定、递归过程中最小值的定义、网站是不是都能爬、requests的header部分是做什么的、百度网分享链接和分析密码的爬取策略、正则表达式如何匹配"所有符号"、get和post的区别、爬虫与数据可视化、爬虫翻页链接的处理、学爬虫有什么好课程、对课上的"干货"力不从心怎么办、有没有可能不分析页面源码也能做抽取、反爬常用手段、验证码问题怎么解决等。 | [L11.3](https://www.bilibili.com/video/av92186118?p=29) | | 2020年5月22日 | 第12讲:爬虫框架初步设计与B站豆瓣初步尝试
摘要:构建爬虫基础类(框架),了解框架、脚手架和库的差别,复习类的设计和构建,对B站和豆瓣的排行榜进行采集,构建完整的信息抽取用正则表达式,熟悉RegexBuilder等正则调试工具的使用,用copy as Curl->requests技巧"克隆"浏览器的访问请求。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_12.ipynb)
![第十二课思维导图](https://github.com/fly51fly/Practical_Python_Programming/blob/master/images/class_12_001.jpg)| [L12.1](https://www.bilibili.com/video/av92186118?p=30) | | - | 第12讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_012.md))
摘要:爬虫能采集视频吗、headers是否必须、正则能否匹配中文、根据不同情况采用不同匹配的爬虫、UTF-8和GBK的区别、课上豆瓣的网址为什么会被加长转义、windows命令行常用命令哪里找、爬虫是什么网站都能抓吗、有密码保护之类手段保护的网址如何怕取、正则里的反斜杠都要转义吗、动态排行榜怎么采集、Python框架除了构建网站还能干啥、有防爬虫无法破解的网站数据怎么获取、页面内容缺少规律性怎么配置、Terminal页面右键没有refresh选项怎么办、Python是爬虫的最佳选择吗、网页拖到下面自动加载或点击更多加载的页面怎么抓取、类似百度翻译的页面怎么找到目标url、爬虫是否有法律风险、什么样的业务适合开发框架等。 | [L12.2](https://www.bilibili.com/video/av92186118?p=31) | -| - | 第13讲:豆瓣爬虫的进化与爬虫基类的完善
摘要:构建豆瓣图书网页单页的完整爬虫,重点解决信息抽取正则表达式的配置和缺失信息项的处理,完善爬虫基类中headers的设置,通过继承机制构建豆瓣图书页面爬虫类。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_13.ipynb) | [L13.1](https://www.bilibili.com/video/av92186118?p=32) | +| 2020年5月29日 | 第13讲:豆瓣爬虫的进化与爬虫基类的完善
摘要:构建豆瓣图书网页单页的完整爬虫,重点解决信息抽取正则表达式的配置和缺失信息项的处理,完善爬虫基类中headers的设置,通过继承机制构建豆瓣图书页面爬虫类。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_13.ipynb) | [L13.1](https://www.bilibili.com/video/av92186118?p=32) | +| - | 第13讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_013.md))
摘要:编程状态不好时该怎么办、课下自己调试感觉困难怎么办、如何收集股票信息并用图表分析、数据的爬取加可视化、遍历过程中为什么不建议修改遍历序列、爬虫在工作中的实例、爬虫的个性化与爬虫基类的重载、除正则表达式以外还有什么其他方式可以解析网页、有些网页加载过程中有多个doc文件该如何处理、批量爬取爬虫的架构、课上的爬虫离商业爬虫有多远、分割文本的爬取有什么高效办法、如何爬取某具体方向的内容、为什么会有乱码。 | [L13.2](https://www.bilibili.com/video/av92186118?p=33) | -学习资源推荐: 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) 3. [Python代码运行可视化](http://www.pythontutor.com/index.html) diff --git a/questions/question_013.md b/questions/question_013.md new file mode 100644 index 0000000..3e49f48 --- /dev/null +++ b/questions/question_013.md @@ -0,0 +1,20 @@ +| 第13讲答疑 问题列表 | +|--------------| +|虽然跟着视频走看上去很简单,但是实际调错时却很难| +|对于一些需要登录才能看到的网页,其内容如何爬取| +|如何收集股票信息,再转成图表分析| +|如何将爬到的数据进行可视化输出呢,比如以图片+文字的形式或者以图表的形式| +|如何理解使用下标index后不会影响遍历的主体| +|爬虫在工作中有哪些实例?| +|爬虫的"个性化"是怎样的呢?实现个性化,一般是在继承的类里进行重载来实现么?| +|除了正则表达式,还有没有其他python网络爬虫的数据解析方式| +|有些网站的network里doc文件不止一个,那个时候该选择哪一个| +|爬虫提取出来的信息能用图表输出么 比如柱状图扇形图之类的 Python里有没有这样的函数呢| +|老师您好,我很想知道对于批量爬取的爬虫构架是怎样的,比如说爬取淘宝多个商家底下的评论| +|老师目前的爬虫代码在N次课程后功能已经越来越丰富,封装性也越来越好,但离商业级爬虫代码还有多远?| +|关于被分割的文本的爬取(比如百度文库,外网论文),怎么才能更加快捷?| +|re.findall()返回结果为数组形式,为什么豆瓣爬虫部分评分那里会出现元组呢?| +|如何用爬虫获取某一类具体方向的内容?直接加关键词?还是获取全部信息再筛选?| +|headers是一种http请求吗| +|为什么会有乱码| +|视频中出现的最后一次报错,然后把items变成大列表,extend的参数变成items[0],这一步不太明白| \ No newline at end of file From 0a8c8b8dbc8da27985a900331946fedf9c910696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: Thu, 4 Jun 2020 21:19:28 +0800 Subject: [PATCH 06/13] class 14 added --- README.md | 1 + code/Python_Class_14.ipynb | 415 +++++++++++++++++++++++++++++++++++++ 2 files changed, 416 insertions(+) create mode 100644 code/Python_Class_14.ipynb diff --git a/README.md b/README.md index ee6c510..b8a39b0 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ | - | 第12讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_012.md))
摘要:爬虫能采集视频吗、headers是否必须、正则能否匹配中文、根据不同情况采用不同匹配的爬虫、UTF-8和GBK的区别、课上豆瓣的网址为什么会被加长转义、windows命令行常用命令哪里找、爬虫是什么网站都能抓吗、有密码保护之类手段保护的网址如何怕取、正则里的反斜杠都要转义吗、动态排行榜怎么采集、Python框架除了构建网站还能干啥、有防爬虫无法破解的网站数据怎么获取、页面内容缺少规律性怎么配置、Terminal页面右键没有refresh选项怎么办、Python是爬虫的最佳选择吗、网页拖到下面自动加载或点击更多加载的页面怎么抓取、类似百度翻译的页面怎么找到目标url、爬虫是否有法律风险、什么样的业务适合开发框架等。 | [L12.2](https://www.bilibili.com/video/av92186118?p=31) | | 2020年5月29日 | 第13讲:豆瓣爬虫的进化与爬虫基类的完善
摘要:构建豆瓣图书网页单页的完整爬虫,重点解决信息抽取正则表达式的配置和缺失信息项的处理,完善爬虫基类中headers的设置,通过继承机制构建豆瓣图书页面爬虫类。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_13.ipynb) | [L13.1](https://www.bilibili.com/video/av92186118?p=32) | | - | 第13讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_013.md))
摘要:编程状态不好时该怎么办、课下自己调试感觉困难怎么办、如何收集股票信息并用图表分析、数据的爬取加可视化、遍历过程中为什么不建议修改遍历序列、爬虫在工作中的实例、爬虫的个性化与爬虫基类的重载、除正则表达式以外还有什么其他方式可以解析网页、有些网页加载过程中有多个doc文件该如何处理、批量爬取爬虫的架构、课上的爬虫离商业爬虫有多远、分割文本的爬取有什么高效办法、如何爬取某具体方向的内容、为什么会有乱码。 | [L13.2](https://www.bilibili.com/video/av92186118?p=33) | +| 2020年6月5日 | 第14讲:爬虫进阶之DOM树与XPath
摘要:DOM的基本概念,DOM树的基本概念,XPath的概念和基本语法,Chrome里XPath Helper扩展的使用,特定目标XPath的获取和精简,用lxml库实现网页源码的解析和XPath目标定位,基于XPath的页面信息分层抽取。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_14.ipynb) | [L14.1](https://www.bilibili.com/video/BV1b7411N7P2?p=34) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/code/Python_Class_14.ipynb b/code/Python_Class_14.ipynb new file mode 100644 index 0000000..17ac2e8 --- /dev/null +++ b/code/Python_Class_14.ipynb @@ -0,0 +1,415 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 爬虫基类" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "from lxml import html" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): ...working... done\n", + "Solving environment: ...working... done\n", + "\n", + "# All requested packages already installed.\n", + "\n" + ] + } + ], + "source": [ + "!conda install requests" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "douban_crawler = MyCrawler('douban.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "content = douban_crawler.download('https://book.douban.com/tag/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "tree = html.fromstring(content)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "book_names = tree.xpath('//h2/a')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'神经网络与深度学习'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "book_names[0].text.strip()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "xpath_str = " + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['神经网络与深度学习',\n", + " 'Python神经网络编程',\n", + " 'Python深度学习',\n", + " '深度学习入门',\n", + " '深度学习的数学',\n", + " '数字思维',\n", + " '深入浅出图神经网络:GNN原理解析',\n", + " 'Neural Networks and Deep Learning',\n", + " '神经网络设计(原书第2版)',\n", + " '神经网络在应用科学和工程中的应用',\n", + " 'Make Your Own Neural Network',\n", + " '图解深度学习与神经网络:从张量到TensorFlow实现',\n", + " 'MATLAB神经网络43个案例分析',\n", + " 'Neural Networks and Learning Machines',\n", + " '神经网络原理(原书第2版)',\n", + " '连接组:造就独一无二的你',\n", + " '神经网络控制',\n", + " 'Neural Networks and Statistical Learning',\n", + " '意识的宇宙',\n", + " 'Unsupervised Learning']" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(map(lambda x: x.text.strip(), tree.xpath(\"//h2/a\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['邱锡鹏 / 机械工业出版社 / 2020年4月10日 / 149.00元',\n", + " '[英]塔里克·拉希德(Tariq Rashid) / 林赐 / 人民邮电出版社 / 2018-4 / 69.00元',\n", + " '[美] 弗朗索瓦•肖莱 / 张亮 / 人民邮电出版社 / 2018-8 / 119.00元',\n", + " '[ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元',\n", + " '[日]涌井良幸、[日]涌井贞美 / 杨瑞龙 / 人民邮电出版社 / 2019-4 / 69.00元',\n", + " '[葡] 阿林多•奥利维拉 / 胡小锐 / 中信出版社 / 2020年1月1日 / 69.00',\n", + " '刘忠雨\\u3000李彦霖\\u3000周洋\\u3000著 / 机械工业出版社 / 2019年12月25日 / 89元',\n", + " 'Michael Nielsen / 2016-1',\n", + " 'Martin T. Hagan、Howard B. Demuth、Mark H. Beale / 章毅 / 机械工业出版社 / 2017-11 / 99.00元',\n", + " '萨马拉辛荷 / 2010-1 / 88.00元',\n", + " 'Tariq Rashid / CreateSpace Independent Publishing Platform / 2016年3月31日 / USD 45.00',\n", + " '张平 / 电子工业出版社 / 2018-10 / 79.00元',\n", + " '王小川、史峰、郁磊、李洋 / 北京航空航天大学出版社 / 2013年8月1日 / CNY 48.00',\n", + " 'Simon O. Haykin / Pearson / 2008年11月28日 / USD 252.40',\n", + " 'Simon Haykin / 叶世伟、史忠植 / 机械工业出版社 / 2004-1 / 69.00元',\n", + " '[美] 承现峻 / 孙天齐 / 清华大学出版社 / 2016-1 / 45',\n", + " '徐丽娜 / 2009-7 / 28.00元',\n", + " 'Ke-Lin Du、M. N. S. Swamy / Springer / 2013年12月7日 / USD 129.00',\n", + " '[美] 杰拉尔德·埃德尔曼、[美] 朱利欧·托诺尼 / 顾凡及 / 上海科学技术出版社 / 2004-1 / 27.00元',\n", + " 'A Bradford Book / 1999年6月11日 / USD 40.00']" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(map(lambda x: x.text.strip(), tree.xpath(\"//div[@class='pub']\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['本书主要介绍神经网络与深度学习中的基础知识、主要模型(卷积神经网络、递归神经网络等)以及在计算机视觉、自然语言处理等领域的应用。',\n", + " '神经网络是一种模拟人脑的神经网络,以期能够实现类人工智能的机器学习\\n技术。\\n本书揭示神经网络背后的概念,并介绍如何通过Python实现神经网络。全书\\n分为3...',\n", + " '本书由Keras之父、现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学...',\n", + " '本书是深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术。书中使用Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从...',\n", + " '《深度学习的数学》基于丰富的图示和具体示例,通俗易懂地介绍了深度学习相关的数学知识。第1章介绍神经网络的概况;第2章介绍理解神经网络所需的数学基础知识;第3...',\n", + " '计算机、细胞和大脑有什么共同之处?计算机是人类设计的电子设备,细胞是经自然进化和选择产生的生物实体,大脑是人类思维的创造者和"容器"。但在某种程度上,它们都...',\n", + " '这是一本从原理、算法、实现、应用4个维度详细讲解图神经网络的著作,在图神经网络领域具有重大的意义。\\n本书作者是图神经网络领域的资深技术专家,作者所在的公司极...',\n", + " 'http://neuralnetworksanddeeplearning.com/',\n", + " '本书是一本易学易懂的神经网络教材,主要讨论网络结构、学习规则、训练技巧和工程应用,紧紧围绕"设计"这一视角组织材料和展开讲解,强调基本原理和训练方法,概念清...',\n", + " '《神经网络在应用科学与工程中的应用:从基本原理到复杂的模式识别》为读者提供了神经网络方面简单但却系统的介绍。\\n《神经网络在应用科学和工程中的应用从基本原理到...',\n", + " '《图解深度学习与神经网络:从张量到TensorFlow实现》是以TensorFlow 为工具介绍神经网络和深度学习的入门书,内容循序渐进,以简单示例和图例的...',\n", + " 'For graduate-level neural network courses offered in the departments of Comput...',\n", + " '★《华尔街日报》2012年度十佳非虚构图书\\n★亚马逊网站2012年编辑选择之百佳图书\\n★《出版人周刊》2012年春季十佳科学类图书\\n【内容简介】\\n基因组让你...',\n", + " '神经网络控制已发展成为"智能控制"的一个新的分支,属先进控制技术,为解决复杂的非线性、不确定、不确知系统的控制问题,开辟了一条新的途径。《神经网络控制(第3...',\n", + " '本书对意识理论进行全面研究,建立在近代神经科学基础上、致力于对意识的产生、及人们对意识的认识如何帮助其"把严格的科学描述与人类知识和经验的宽广领域联系起来"...',\n", + " 'Since its founding in 1989 by Terrence Sejnowski, Neural Computation has becom...']" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(map(lambda x: x.text.strip(), tree.xpath(\"//div[@class='info']/p\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[1;31mInit signature:\u001b[0m \u001b[0mmap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m/\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mDocstring:\u001b[0m \n", + "map(func, *iterables) --> map object\n", + "\n", + "Make an iterator that computes the function using arguments from\n", + "each of the iterables. Stops when the shortest iterable is exhausted.\n", + "\u001b[1;31mType:\u001b[0m type\n", + "\u001b[1;31mSubclasses:\u001b[0m \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "map" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "book_infos = tree.xpath(\"//li[@class='subject-item']\")" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "神经网络与深度学习 https://book.douban.com/subject/35044046/ 邱锡鹏 / 机械工业出版社 / 2020年4月10日 / 149.00元 \n", + " 本书主要介绍神经网络与深度学习中的基础知识、主要模型(卷积神经网络、递归神经网络等)以及在计算机视觉、自然语言处理等领域的应用。\n", + "Python神经网络编程 https://book.douban.com/subject/30192800/ [英]塔里克·拉希德(Tariq Rashid) / 林赐 / 人民邮电出版社 / 2018-4 / 69.00元 \n", + " 神经网络是一种模拟人脑的神经网络,以期能够实现类人工智能的机器学习\n", + "技术。\n", + "本书揭示神经网络背后的概念,并介绍如何通过Python实现神经网络。全书\n", + "分为3...\n", + "Python深度学习 https://book.douban.com/subject/30293801/ [美] 弗朗索瓦•肖莱 / 张亮 / 人民邮电出版社 / 2018-8 / 119.00元 \n", + " 本书由Keras之父、现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学...\n", + "深度学习入门 https://book.douban.com/subject/30270959/ [ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元 \n", + " 本书是深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术。书中使用Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从...\n", + "深度学习的数学 https://book.douban.com/subject/33414479/ [日]涌井良幸、[日]涌井贞美 / 杨瑞龙 / 人民邮电出版社 / 2019-4 / 69.00元 \n", + " 《深度学习的数学》基于丰富的图示和具体示例,通俗易懂地介绍了深度学习相关的数学知识。第1章介绍神经网络的概况;第2章介绍理解神经网络所需的数学基础知识;第3...\n", + "数字思维 https://book.douban.com/subject/34941715/ [葡] 阿林多•奥利维拉 / 胡小锐 / 中信出版社 / 2020年1月1日 / 69.00 \n", + " 计算机、细胞和大脑有什么共同之处?计算机是人类设计的电子设备,细胞是经自然进化和选择产生的生物实体,大脑是人类思维的创造者和"容器"。但在某种程度上,它们都...\n", + "深入浅出图神经网络:GNN原理解析 https://book.douban.com/subject/34927262/ 刘忠雨 李彦霖 周洋 著 / 机械工业出版社 / 2019年12月25日 / 89元 \n", + " 这是一本从原理、算法、实现、应用4个维度详细讲解图神经网络的著作,在图神经网络领域具有重大的意义。\n", + "本书作者是图神经网络领域的资深技术专家,作者所在的公司极...\n", + "Neural Networks and Deep Learning https://book.douban.com/subject/26727997/ Michael Nielsen / 2016-1 \n", + " http://neuralnetworksanddeeplearning.com/\n", + "神经网络设计(原书第2版) https://book.douban.com/subject/30236893/ Martin T. Hagan、Howard B. Demuth、Mark H. Beale / 章毅 / 机械工业出版社 / 2017-11 / 99.00元 \n", + " 本书是一本易学易懂的神经网络教材,主要讨论网络结构、学习规则、训练技巧和工程应用,紧紧围绕"设计"这一视角组织材料和展开讲解,强调基本原理和训练方法,概念清...\n", + "神经网络在应用科学和工程中的应用 https://book.douban.com/subject/4146246/ 萨马拉辛荷 / 2010-1 / 88.00元 \n", + " 《神经网络在应用科学与工程中的应用:从基本原理到复杂的模式识别》为读者提供了神经网络方面简单但却系统的介绍。\n", + "《神经网络在应用科学和工程中的应用从基本原理到...\n", + "Make Your Own Neural Network https://book.douban.com/subject/26945232/ Tariq Rashid / CreateSpace Independent Publishing Platform / 2016年3月31日 / USD 45.00 \n", + " N/A\n", + "图解深度学习与神经网络:从张量到TensorFlow实现 https://book.douban.com/subject/30333961/ 张平 / 电子工业出版社 / 2018-10 / 79.00元 \n", + " 《图解深度学习与神经网络:从张量到TensorFlow实现》是以TensorFlow 为工具介绍神经网络和深度学习的入门书,内容循序渐进,以简单示例和图例的...\n", + "MATLAB神经网络43个案例分析 https://book.douban.com/subject/26388161/ 王小川、史峰、郁磊、李洋 / 北京航空航天大学出版社 / 2013年8月1日 / CNY 48.00 \n", + " N/A\n", + "Neural Networks and Learning Machines https://book.douban.com/subject/2584657/ Simon O. Haykin / Pearson / 2008年11月28日 / USD 252.40 \n", + " For graduate-level neural network courses offered in the departments of Comput...\n", + "神经网络原理(原书第2版) https://book.douban.com/subject/1138922/ Simon Haykin / 叶世伟、史忠植 / 机械工业出版社 / 2004-1 / 69.00元 \n", + " N/A\n", + "连接组:造就独一无二的你 https://book.douban.com/subject/26666358/ [美] 承现峻 / 孙天齐 / 清华大学出版社 / 2016-1 / 45 \n", + " ★《华尔街日报》2012年度十佳非虚构图书\n", + "★亚马逊网站2012年编辑选择之百佳图书\n", + "★《出版人周刊》2012年春季十佳科学类图书\n", + "【内容简介】\n", + "基因组让你...\n", + "神经网络控制 https://book.douban.com/subject/3890040/ 徐丽娜 / 2009-7 / 28.00元 \n", + " 神经网络控制已发展成为"智能控制"的一个新的分支,属先进控制技术,为解决复杂的非线性、不确定、不确知系统的控制问题,开辟了一条新的途径。《神经网络控制(第3...\n", + "Neural Networks and Statistical Learning https://book.douban.com/subject/26422529/ Ke-Lin Du、M. N. S. Swamy / Springer / 2013年12月7日 / USD 129.00 \n", + " N/A\n", + "意识的宇宙 https://book.douban.com/subject/1159821/ [美] 杰拉尔德·埃德尔曼、[美] 朱利欧·托诺尼 / 顾凡及 / 上海科学技术出版社 / 2004-1 / 27.00元 \n", + " 本书对意识理论进行全面研究,建立在近代神经科学基础上、致力于对意识的产生、及人们对意识的认识如何帮助其"把严格的科学描述与人类知识和经验的宽广领域联系起来"...\n", + "Unsupervised Learning https://book.douban.com/subject/6529821/ A Bradford Book / 1999年6月11日 / USD 40.00 \n", + " Since its founding in 1989 by Terrence Sejnowski, Neural Computation has becom...\n" + ] + } + ], + "source": [ + "for book_info in book_infos:\n", + " book_name_elem = book_info.xpath('.//h2/a')[0]\n", + " book_name = book_name_elem.text.strip()\n", + " book_url = book_name_elem.attrib['href']\n", + " book_pub_info = book_info.xpath(\".//div[@class='pub']\")[0].text.strip()\n", + " book_intro = 'N/A'\n", + " book_intro_elem = book_info.xpath(\".//div[@class='info']/p\")\n", + " if book_intro_elem:\n", + " book_intro = book_intro_elem[0].text.strip()\n", + " print(book_name, book_url, book_pub_info, '\\n', book_intro)\n", + "# break" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://book.douban.com/subject/35044046/'" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "book_name_elem.attrib['href']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 248ce32e7083b25d1e8d458123efab8b0bdabd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: Sat, 6 Jun 2020 19:27:51 +0800 Subject: [PATCH 07/13] QA 14 added --- README.md | 1 + questions/question_014.md | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 questions/question_014.md diff --git a/README.md b/README.md index b8a39b0..055f6bb 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ | 2020年5月29日 | 第13讲:豆瓣爬虫的进化与爬虫基类的完善
摘要:构建豆瓣图书网页单页的完整爬虫,重点解决信息抽取正则表达式的配置和缺失信息项的处理,完善爬虫基类中headers的设置,通过继承机制构建豆瓣图书页面爬虫类。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_13.ipynb) | [L13.1](https://www.bilibili.com/video/av92186118?p=32) | | - | 第13讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_013.md))
摘要:编程状态不好时该怎么办、课下自己调试感觉困难怎么办、如何收集股票信息并用图表分析、数据的爬取加可视化、遍历过程中为什么不建议修改遍历序列、爬虫在工作中的实例、爬虫的个性化与爬虫基类的重载、除正则表达式以外还有什么其他方式可以解析网页、有些网页加载过程中有多个doc文件该如何处理、批量爬取爬虫的架构、课上的爬虫离商业爬虫有多远、分割文本的爬取有什么高效办法、如何爬取某具体方向的内容、为什么会有乱码。 | [L13.2](https://www.bilibili.com/video/av92186118?p=33) | | 2020年6月5日 | 第14讲:爬虫进阶之DOM树与XPath
摘要:DOM的基本概念,DOM树的基本概念,XPath的概念和基本语法,Chrome里XPath Helper扩展的使用,特定目标XPath的获取和精简,用lxml库实现网页源码的解析和XPath目标定位,基于XPath的页面信息分层抽取。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_14.ipynb) | [L14.1](https://www.bilibili.com/video/BV1b7411N7P2?p=34) | +| - | 第14讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_014.md))
摘要:如何深入了解xpath、xpath能否完全代替正则表达式、大爬虫也需要对每个网页配置抽取表达式吗、访问图片时拒绝访问如何处理、xpath里的@href什么意思、xpath的绝对路径和相对路径有何区别、DOM树与C++的树一样吗、xpath与正则表达式适用场景如何效率比较及怎样选择、遇到具体变成问题怎么找解决方案、xpath helper安装不了怎么办、lxml解析为什么要解码、表格数据如何采集、DOM和xpath的关系、pycharm怎么安装lxml、爬虫在生活中的应用、豆瓣书名副标题的采集问题、包含子节点的节点如何获取全部文本、xpath能否用于普通字符串、beautifulsoup和lxml在解析方面有什么区别吗、python能提供网页服务吗、模型到底是什么、没有插件如何快速获取xpath等。 | [L14.2](https://www.bilibili.com/video/BV1b7411N7P2?p=35) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/questions/question_014.md b/questions/question_014.md new file mode 100644 index 0000000..c888cd0 --- /dev/null +++ b/questions/question_014.md @@ -0,0 +1,36 @@ +| 第14讲答疑 问题列表 | +|--------------| +|对于路径访问的知识老师能不能在在介绍详细点
除了视频里介绍的老师能不能再介绍些其他的操作| +|xpath可以完全代替正则运用吗| +|"大爬虫"的信息爬取可以优化到什么程度,应该不用自己再对每个网址都单独写表达式吧| +|采集到图片的URL后如何,如何展示图片啊,直接点进去的话提示服务器拒绝请求。| +|在XPath helper最后找url时(//h2/a/@href)为什么要加@| +|请问Xpath取绝对路径和相对路径有什么区别,或者优缺点?| +|这个dom树对应的是c++的树吗?二者有什么区别?| +|请问怎么判断什么时候用xpath或正则表达式来定位呢?| +|Xpath路径怎么选择| +|想问问老师有没有那种比较准确可以询问不会的代码或者了解用法的社区(感觉有的时候百度上的东西杂而且不一定对...)| +|xpath helper的官方下载渠道需要vpn,用其它渠道下载会安装失败| +|XPath一共有几种类型的节点| +|不太理解为什么使用lxml之前要先经过utf-8解码| +|book.info函数后面两个斜杠和一个斜杠的区别仍有些不清楚| +|Xpath里绝对路径和相对路径有什么区别,我们应该怎么用| +|XPath方式和正则表达式方式两种方式谁更好呢?或者说各有什么优缺点呢?个人感觉XPath获取信息的效率要高一些| +|可不可以爬取比如一个Excel表格中的内容?(表格中有很多数据想用类似正则提取需要的内容)但表格没有网址,不知怎么弄。| +|xmldom和xpath是什么关系| +|那个豆瓣图书标签那为什么按住shift晃啊晃就可以显示那个节点对应的XPATH?| +|如果是pycharm该怎么装那个包呢?| +|爬虫在生活中可以应用到哪些方面上呢| +|不是很明白为什么book_info.xpath(...)后面要加[0]?| +|那个xpath helper不太会弄。。。| +|dom和xpath能否联合使用?| +|如何判断爬虫是采用DOM树操作还是正则呢?二者对比互相有哪些明显的优势?| +|书名有两部分的,后面部分都没有爬取到;如果一个页面有文档预览,如何爬里面的字?(有插件推荐吗?| +|使用xpath提取页面数据时,//text()与/text()的区别是什么| +|老师请问,xpath是用在浏览器已经修饰过的网页较为方便,对于普通字符串的搜索也能方便的写出xpath的索引表达式么| +|beautifulsoup和lxml针对网页形成的树形结构有什么区别。| +|python可以像html和css一样做出一个成熟网页吗| +|感觉哪里都有都有点若隐若现的疑问,但是组织不出来| +|模型究竟是什么?(看了很多解释依然不是很明白)如何学会提炼模型?模型与抽象的关系是什么?数学有数学模型,计算机图像有3d模型,文档对象模型是什么模型?| +|DOM树有什么特别的作用吗?| +|xpath能不能从源代码中简便的看出来,比如根据它的div,li之类的,主要是因为xpath helper没法下载。| \ No newline at end of file From d949eb440633ed307931678d09df2525a9118fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年6月12日 07:04:37 +0800 Subject: [PATCH 08/13] Class 15 added --- README.md | 1 + code/Python_Class_15.ipynb | 842 +++++++++++++++++++++++++++++++++++++ 2 files changed, 843 insertions(+) create mode 100644 code/Python_Class_15.ipynb diff --git a/README.md b/README.md index 055f6bb..48a5eb5 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ | - | 第13讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_013.md))
摘要:编程状态不好时该怎么办、课下自己调试感觉困难怎么办、如何收集股票信息并用图表分析、数据的爬取加可视化、遍历过程中为什么不建议修改遍历序列、爬虫在工作中的实例、爬虫的个性化与爬虫基类的重载、除正则表达式以外还有什么其他方式可以解析网页、有些网页加载过程中有多个doc文件该如何处理、批量爬取爬虫的架构、课上的爬虫离商业爬虫有多远、分割文本的爬取有什么高效办法、如何爬取某具体方向的内容、为什么会有乱码。 | [L13.2](https://www.bilibili.com/video/av92186118?p=33) | | 2020年6月5日 | 第14讲:爬虫进阶之DOM树与XPath
摘要:DOM的基本概念,DOM树的基本概念,XPath的概念和基本语法,Chrome里XPath Helper扩展的使用,特定目标XPath的获取和精简,用lxml库实现网页源码的解析和XPath目标定位,基于XPath的页面信息分层抽取。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_14.ipynb) | [L14.1](https://www.bilibili.com/video/BV1b7411N7P2?p=34) | | - | 第14讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_014.md))
摘要:如何深入了解xpath、xpath能否完全代替正则表达式、大爬虫也需要对每个网页配置抽取表达式吗、访问图片时拒绝访问如何处理、xpath里的@href什么意思、xpath的绝对路径和相对路径有何区别、DOM树与C++的树一样吗、xpath与正则表达式适用场景如何效率比较及怎样选择、遇到具体变成问题怎么找解决方案、xpath helper安装不了怎么办、lxml解析为什么要解码、表格数据如何采集、DOM和xpath的关系、pycharm怎么安装lxml、爬虫在生活中的应用、豆瓣书名副标题的采集问题、包含子节点的节点如何获取全部文本、xpath能否用于普通字符串、beautifulsoup和lxml在解析方面有什么区别吗、python能提供网页服务吗、模型到底是什么、没有插件如何快速获取xpath等。 | [L14.2](https://www.bilibili.com/video/BV1b7411N7P2?p=35) | +| 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。 | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/code/Python_Class_15.ipynb b/code/Python_Class_15.ipynb new file mode 100644 index 0000000..90bbd40 --- /dev/null +++ b/code/Python_Class_15.ipynb @@ -0,0 +1,842 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "from lxml import html" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "douban_crawler = MyCrawler('douban.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "content = douban_crawler.download('https://book.douban.com/tag/?view=type')\n", + "tree = html.fromstring(content)\n", + "tag_url_matches = tree.xpath('//td/a/@href')" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "tag_list = [tag_url[5:] for tag_url in tag_url_matches]" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'小说'" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tag_list[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD\n" + ] + } + ], + "source": [ + "import urllib.parse\n", + "print(urllib.parse.quote('人工智能'))" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=0&type=T\n", + "Last Start ID: 500\n", + "为什么: 关于因果关系的新科学\n", + "智能时代: 大数据与智能革命重新定义未来\n", + "生命3.0: 人工智能时代,人类的进化与重生\n", + "哥德尔、艾舍尔、巴赫: 集异璧之大成\n", + "Python深度学习\n", + "仿生人会梦见电子羊吗?\n", + "奇点临近: 当计算机智能超越人类\n", + "智能商业\n", + "复杂\n", + "深度学习\n", + "动手学深度学习\n", + "机器学习\n", + "深度学习推荐系统\n", + "自然语言处理入门\n", + "AI·未来\n", + "人工智能的未来\n", + "认知: 人行为背后的思维与智能\n", + "深度学习入门: 基于Python的理论与实现\n", + "本源\n", + "天才与算法: 人脑与AI的数学思维\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=20&type=T\n", + "人工智能: 一种现代的方法(第3版)(影印版)\n", + "深度学习: 智能时代的核心驱动力量\n", + "人工智能之不能\n", + "统计学习方法\n", + "人工智能\n", + "机器人叛乱: 在达尔文时代找到意义\n", + "Python神经网络编程\n", + "终极算法: 机器学习和人工智能如何重塑世界\n", + "复杂\n", + "创造性思维: 人工智能之父马文·明斯基论教育\n", + "统计学习方法(第2版)\n", + "Pattern Recognition and Machine Learning\n", + "人工智能基础(高中版): 高中版\n", + "智能计算系统\n", + "人工科学: 复杂性面面观\n", + "暗知识:机器认知如何颠覆商业和社会: 机器认知如何颠覆商业和社会\n", + "智慧的疆界: 从图灵机到人工智能\n", + "神经网络与深度学习\n", + "心智社会: 从细胞到人工智能,人类思维的优雅解读\n", + "人工智能时代: 人机共生下财富、工作与思维的大未来\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=40&type=T\n", + "百面机器学习: 算法工程师带你去面试\n", + "人工智能哲学\n", + "集体智慧编程\n", + "人工智能简史\n", + "第二次机器革命: 数字化技术将如何改变我们的经济与社会\n", + "第二次机器革命: 数字化技术将如何改变我们的经济与社会\n", + "人工智能: 一种现代方法(第2版)(中文版)\n", + "人工智能全球格局: 未来趋势与中国位势\n", + "皇帝新脑: 有关电脑、人脑及物理定律\n", + "人生算法\n", + "人类的终极命运: 从旧石器时代到人工智能的未来\n", + "数字思维\n", + "无人驾驶: 人工智能将从颠覆驾驶开始,全面重构人类生活\n", + "人类的认知: 思维的信息加工理论\n", + "GEB——一条永恒的金带\n", + "人工智能: 一种现代的方法\n", + "深度学习:基于案例理解深度神经网络\n", + "算法霸权: 数学杀伤性武器的威胁\n", + "智能的本质 人工智能与机器人领域的64个大问题: 人工智能与机器人领域的64个大问题\n", + "人工智能 (第2版)\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=60&type=T\n", + "深入浅出图神经网络:GNN原理解析\n", + "Bayesian Reasoning and Machine Learning\n", + "The Book of Why: The New Science of Cause and Effect\n", + "必然\n", + "直觉泵和其他思考工具\n", + "软件体的生命周期: 特德·姜科幻小说集\n", + "智能时代: 当所有的机器都能学习思考,我们的生活会如何改变\n", + "推荐系统实践\n", + "AI极简经济学\n", + "Learning From Data: A Short Course\n", + "情感机器: 人类思维与人工智能的未来\n", + "云球(第一部)\n", + "科学的极致:漫谈人工智能\n", + "量子计算机简史\n", + "语音与语言处理: :自然语言处理、计算语言学和语音识别导论\n", + "艾伦·图灵传: 如谜的解谜者\n", + "最有人性的"人": 人工智能带给我们的启示\n", + "被看见的力量: 快手是什么\n", + "心智、语言和机器: 维特根斯坦哲学和人工智能科学的对话\n", + "控制论: 或关于在动物和机器中控制和通信的科学\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=80&type=T\n", + "Python深度学习:基于PyTorch\n", + "如何创造思维: 人类思想所揭示出的奥秘\n", + "错觉: AI如何通过数据挖掘误导我们\n", + "人工智能产品经理——AI时代PM修炼手册\n", + "机器崛起: 遗失的控制论历史\n", + "Chatbot从0到1: 对话式交互设计实践指南\n", + "未来地图: 技术、商业和我们的选择\n", + "凸优化\n", + "超级智能: 路线图、危险性与应对策略\n", + "不会被机器替代的人: 智能时代的生存策略\n", + "机器学习实战\n", + "人生新算法: 用人工智能解读时间、幸运与财富\n", + "图灵的秘密: 他的生平、思想及论文解读\n", + "Reinforcement Learning: An Introduction (second edition)\n", + "Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques for Building Intelligent Systems\n", + "脑机穿越: 脑机接口改变人类未来\n", + "深入理解AutoML和AutoDL:构建自动化机器学习与深度学习平台\n", + "智能战略\n", + "计算机与人脑\n", + "心灵的未来\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=100&type=T\n", + "Artificial Intelligence: A Modern Approach\n", + "知识图谱:概念与技术\n", + "深度思考: 人工智能的终点与人类创造力的起点\n", + "灵魂机器的时代: 当计算机超过人类智能时/开放人文\n", + "人工智能的未来\n", + "Tensorflow:实战Google深度学习框架\n", + "智能浪潮: 增强时代来临\n", + "KK三部曲: 失控+科技想要什么+必然\n", + "智能革命: 迎接人工智能时代的社会、经济与文化变革\n", + "机器学习\n", + "Superintelligence: Paths, Dangers, Strategies\n", + "人机平台:商业未来行动路线图\n", + "人人都该懂的人工智能\n", + "The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition\n", + "Learning OpenCV 3: Computer Vision in C++ with the OpenCV Library\n", + "携程人工智能实践\n", + "产品经理进阶:100个案例搞懂人工智能\n", + "神经网络在应用科学和工程中的应用: 从基本原理到复杂的模式识别\n", + "Deep Learning: Adaptive Computation and Machine Learning series\n", + "黑镜: 科幻与悬疑的绝佳组合之书\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=120&type=T\n", + "与机器人共舞\n", + "Python机器学习基础教程\n", + "Probabilistic Graphical Models: Principles and Techniques\n", + "机器学习实战:基于Scikit-Learn和TensorFlow\n", + "第四次革命\n", + "计算机视觉: 一种现代方法 第二版\n", + "神经网络设计\n", + "Foundations of Machine Learning\n", + "Information Theory, Inference and Learning Algorithms\n", + "图解机器学习\n", + "被人工智能操控的金融业: 人工知能が金融を支配する日\n", + "强化学习(第2版)\n", + "Godel, Escher, Bach: An Eternal Golden Braid\n", + "统计自然语言处理基础\n", + "基于深度学习的自然语言处理\n", + "深度学习导论\n", + "机器情人: 当情感被算法操控\n", + "神经网络设计(原书第2版)\n", + "数据挖掘导论: Introduction to Data Mining\n", + "智能机器如何思考: 深度神经网络的秘密\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=140&type=T\n", + "机器视觉\n", + "统计学习理论\n", + "人工智能导论: Introduction to Artificial Intelligence\n", + "Deep Learning with Python\n", + "Artificial Intelligence for Games, Second Edition: Intelligence for Games\n", + "南京大学人工智能本科专业教育培养体系: 培养体系\n", + "信息论、推理与学习算法\n", + "TensorFlow:实战Google深度学习框架(第2版)\n", + "计算机不能做什么: 人工智能的极限\n", + "你一定爱读的人工智能简史\n", + "人工智能产品经理:人机对话系统设计逻辑探究\n", + "推荐系统\n", + "硬战:人工智能时代的爆款产品\n", + "人工智能哲学\n", + "大脑的未来: 神经科学的愿景与隐忧\n", + "我们最后的发明: 人工智能与人类时代的终结\n", + "情感分析:挖掘观点、情感和情绪: 挖掘观点、情感和情绪\n", + "实用多元统计分析\n", + "The Singularity Is Near: When Humans Transcend Biology\n", + "决战大数据(升级版): 大数据的关键思考\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=160&type=T\n", + "分布式机器学习:算法、理论与实践\n", + "给孩子的人工智能图解: 明天开始就想用上的68个关键词\n", + "知识图谱:方法、实践与应用\n", + ""AI失业"时代生存指南: 未来5年在职场会发生什么\n", + "AI赋能:AI重新定义产品经理\n", + "艾比斯之梦\n", + "合作的复杂性: 基于参与者的竞争与合作模型\n", + "微粒社会\n", + "人工智能: 复杂问题求解的结构和策略\n", + "深度学习与图像识别:原理与实践: 学习图像识别,这本书轻松带你从0到100!阿里巴巴达摩院算法专家领衔\n", + "对冲之王(经典版): 华尔街量化投资传奇\n", + "Data-Driven Science and Engineering: Machine Learning, Dynam\n", + "Introduction to Information Retrieval\n", + "机器翻译\n", + "机器人法\n", + "算法交易员:会赚钱的人工智能\n", + "金羊毛: 世界科幻大师丛书\n", + "万物都相爱\n", + "神经网络与机器学习(原书第3版)\n", + "游戏人工智能\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=180&type=T\n", + "剑桥五重奏——机器能思考吗?: 机器能思考吗?\n", + "皇帝新脑\n", + "Introduction to Linear Algebra: Fifth Edition\n", + "语言与心智\n", + "强化学习:原理与Python实现\n", + "机·智: 从数字化车间走向智能制造\n", + "What Computers Still Can't Do: A Critique of Artificial Reason\n", + "2小时读懂物联网\n", + "人工智能: 人工智能·智能系统指南(原书第2版)\n", + "Machine Learning: A Probabilistic Perspective\n", + "The Sciences of the Artificial\n", + "人工智能十万个为什么:热AI\n", + "人工智能与法律的对话\n", + "如何创造可信的AI\n", + "人工智能: 一种现代的方法(第2版)(影印版)\n", + "智能语音时代:商业竞争、技术创新与虚拟永生: 麻省理工科技评论2019全球十大突破性技术,解密苹果、谷歌、Facebook、微\n", + "虚拟人\n", + "机器学习:算法背后的理论与优化(中外学者论AI)\n", + "计算机与人脑\n", + "意识的解释\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=200&type=T\n", + "文本数据管理与分析:信息检索与文本挖掘的实用导论\n", + "无心的机器\n", + "Programming Game AI by Example\n", + "Human Compatible: Artificial Intelligence and the Problem of Control\n", + "数字中国: 区块链、智能革命与国家治理的未来\n", + "人工智能及其应用: 第4版\n", + "和机器人一起进化: Generation Robot\n", + "人机共生:谁是不会被机器替代的人(托马斯·达文波特智能商业五部曲)\n", + "统计自然语言处理(第2版)\n", + "Foundations of Statistical Natural Language Processing\n", + "机器学习与优化\n", + "剑桥五重奏: 机器能思考吗\n", + "爱犯错的智能体\n", + "人工智能时代的教育革命\n", + "Causality: Models, Reasoning and Inference\n", + "无所遁形\n", + "数据科学家访谈录: 25位著名数据科学家的真知灼见\n", + "What to Think About Machines That Think: Today's Leading Thinkers on the Age of Machine Intelligence\n", + "无人军队: 自主武器与未来战争\n", + "算法的陷阱: 超级平台、算法垄断与场景欺骗\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=220&type=T\n", + "Neural Networks and Deep Learning\n", + "人工智能会抢哪些工作\n", + "深度学习的数学\n", + "进击的科技: 从爱因斯坦到人工智能\n", + "人工智能简史\n", + "技术奇点\n", + "有限理性适应性工具箱: 适应性工具箱\n", + "图灵的大教堂: 数字宇宙开启智能时代\n", + "Advances in Financial Machine Learning\n", + "心智: 认知科学导论\n", + "Gödel, Escher, Bach: An Eternal Golden Braid\n", + "Neural Networks and Deep Learning\n", + "Army of None: Autonomous Weapons and the Future of War\n", + "工具,还是武器?: 直面人类科技最紧迫的争议性问题\n", + "模式识别\n", + "游戏人工智能编程案例精粹\n", + "Make Your Own Neural Network\n", + "Artificial Intelligence for Everyone\n", + "用户体验设计指南:从方法论到产品设计实践\n", + "白话大数据与机器学习\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=240&type=T\n", + "Python Machine Learning: Machine Learning and Deep Learning with Python, scikit-learn, and TensorFlow, 2nd Edition\n", + "模式识别: 第四版\n", + "风向: 如何应对互联网变革下的知识焦虑、不确定与个人成长\n", + "人类活动中的理性\n", + "创世纪\n", + "The Creativity Code\n", + "TensorFlow机器学习项目实战\n", + "自动机器学习入门与实践: 使用Python\n", + "情感与学习技术的新视角(21世纪人类学习的革命)\n", + "计算机视觉: 模型、学习和推理\n", + "机器生命的秘密\n", + "人工智能\n", + "TensorFlow实战\n", + "Vision: A Computational Investigation into the Human Representation and Processing of Visual Information\n", + "Python编程第4版\n", + "未来简史\n", + "文本数据挖掘\n", + "人工智能: 复杂问题求解的结构和策略(原书第6版)\n", + "Prediction Machines: The Simple Economics of Artificial Intelligence\n", + "人工智能超越人类:技术奇点的冲击\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=260&type=T\n", + "认知科学哲学问题研究\n", + "智能问答与深度学习\n", + "Learning Deep Architectures for AI\n", + "人工智能: 开启颠覆性智能时代\n", + "产品改变世界: Siri如何成功创造千亿市场\n", + "Python Machine Learning Cookbook\n", + "数字创世纪: 人工生命的新科学\n", + "区块链与人工智能:数字经济新时代: 畅销书《区块链与新经济:数字货币2.0时代》全新修订升级版。《互联网\n", + "面向机器智能的TensorFlow实践\n", + "数学之美\n", + "A New Kind of Science\n", + "计算机视觉: 算法与应用\n", + "智能问答\n", + "集体智慧编程\n", + "Neural Network Methods in Natural Language Processing\n", + "神经网络原理(原书第2版)\n", + "人工科学\n", + "Handbook of Collective Intelligence\n", + "Artificial Intelligence: A Modern Approach , 4th Edition\n", + "隐藏的行为: 塑造未来的7种无形力量\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=280&type=T\n", + "预见人力资源——新时代HR的进化方法论\n", + "自然语言处理综论(第二版)\n", + "The Modularity of Mind: An Essay on Faculty Psychology\n", + "教育的未来:人工智能时代的教育变革\n", + "区块链+人工智能 下一个改变世界的经济新模式: 下一个改变世界的经济新模式\n", + "白话深度学习与TensorFlow\n", + "图像局部不变性特征与描述\n", + "机器之心\n", + "未来医疗: 智能时代的个体医疗革命\n", + "人工智能导论\n", + ""深蓝"揭秘: 追寻人工智能圣杯之旅\n", + "新机器的灵魂\n", + "知识图谱\n", + "逻辑人生: 哥德尔传\n", + "You Look Like a Thing and I Love You: How Artificial Intelligence Works and Why It's Making the World a Weirder Place\n", + "机器学习: 贝叶斯和优化方法\n", + "解密搜索引擎技术实战\n", + "我是阿爾法: 論法和人工智能\n", + "Artificial Intelligence for Games (The Morgan Kaufmann Series in Interactive 3D Technology)\n", + "Introduction to Automata Theory,Languages, and Computation\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=300&type=T\n", + "I Am a Strange Loop\n", + "仿生人会梦见电子羊吗?\n", + "Automation and Utopia: Human Flourishing in a World without Work\n", + "无人机网络与通信\n", + "贝叶斯网引论\n", + "贤二机器僧漫游人工智能\n", + "Python数据分析与挖掘实战\n", + "特征提取与图像处理\n", + "狡猾的情感: 为何愤怒、嫉妒、偏见让我们的决策更理性\n", + "Artificial Intelligence: A Very Short Introducion\n", + "Artificial Intelligence: Structures and Strategies for Complex Problem Solving (6th Edition)\n", + "人工智能狂潮: 机器人会超越人类吗?\n", + "Computability and Logic\n", + "人工智能导论: 人工智能导论\n", + "刷脸背后: 人脸检测 人脸识别 人脸检索\n", + "可穿戴创意设计:技术与时尚的融合\n", + "Artificial Intelligence in the Age of Neural Networks and Brain Computing\n", + "今日简史: 人类命运大议题\n", + "AI改变设计——人工智能时代的设计师生存手册\n", + "贪婪的大脑: 为何人类会无止境地寻求意义\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=320&type=T\n", + "智能客服机器人\n", + "Understanding Machine Learning: From Theory to Algorithms\n", + "人工智能: 国家人工智能战略行动抓手\n", + "AI思维: 从数据中创造价值的炼金术\n", + "Google如何统治世界:人工智能会是人类的敌人吗?\n", + "情感解剖图鉴\n", + "科学+预见人工智能\n", + "机器学习系统设计\n", + "控制论: 或关于在动物和机器中控制和通信的科学\n", + "新机器的灵魂\n", + "经济奇点: 人工智能时代,我们将如何谋生?\n", + "我眼中的Master\n", + "让生活更美好: 无线电科普丛书\n", + "MXNet深度学习实战\n", + "罐装神仙-壹\n", + "数理情感学: 人类情感的数学逻辑\n", + "Architects of Intelligence: The truth about AI from the people building it\n", + "人工智能原理与方法\n", + "第一本无人驾驶技术书\n", + "白话机器学习算法\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=340&type=T\n", + "感情研究指南: 情感史的框架\n", + "机器文明数学本质\n", + "Machine Learning: An Algorithmic Perspective\n", + "数据挖掘中的新方法:支持向量机: 支持向量机\n", + "Mind as Machine: A History of Cognitive Science\n", + "孤高求败: 阿尔法GO60局精彩绝招详解\n", + "人机共生: 当爱情、战争和生活都自动化了,人类该如何自处\n", + "走近2050:注意力、互联网与人工智能\n", + "Theory of Self-Reproducing Automata\n", + "从无限运算力到无限想象力:设计人工智能概览\n", + "深度学习核心技术与实践\n", + "机器世界\n", + "人工智能关我什么事: 全面了解人工智能如何改变日常生活\n", + "喝掉这"罐"书\n", + "游戏编程中的人工智能技术\n", + "Surfaces and Essences: Analogy as the Fuel and Fire of Thinking\n", + "Artificial Intelligence: Foundations of Computational Agents\n", + "超人诞生: 人类增强的新技术\n", + "没有思想的世界: 科技巨头对独立思考的威胁\n", + "ROS机器人程序设计: (原书第二版)\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=360&type=T\n", + "人工智能新时代:全球人工智能应用真实落地50例\n", + "起点人\n", + "大腦解密手冊: 誰在做決策、現實是什麼、為何沒有人是孤島、科技將如何改變大腦的未\n", + "游戏开发中的人工智能\n", + "机器学习导论(原书第3版)\n", + "概率图模型:原理与技术\n", + "Python自然语言处理实战: 核心技术与算法\n", + "推荐系统开发实战\n", + "机器危机\n", + "Python自然语言处理\n", + "神经网络控制\n", + "玩家\n", + "漫画机器学习入门\n", + "科技之巅: 《麻省理工科技评论》50大全球突破性技术深度剖析\n", + "超级技术: 改变未来社会和商业的技术趋势\n", + "Computer Vision: Models, Learning, and Inference\n", + "内向者沟通圣经\n", + "机器学习: 实用案例解析\n", + "情感计算\n", + "白话强化学习与PyTorch\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=380&type=T\n", + "营销三大算法: 引领营销进入算法时代\n", + "《裂变:秒懂人工智能的基础课》\n", + "AI+医疗健康: 智能化医疗健康的应用与未来\n", + "Python程序员面试笔试宝典\n", + "统计学关我什么事: 生活中的极简统计学\n", + "灵魂机器的时代:当计算机超过人类智能时\n", + "计算机视觉: 一种现代方法\n", + "机器与人:埃森哲论新人工智能: 埃森哲论新人工智能\n", + "游戏人工智能编程案例精粹\n", + "解析几何 (第三版)\n", + "精通数据科学:从线性回归到深度学习\n", + "模式分类: 原书第2版\n", + "人脸识别原理及算法: 动态人脸识别系统研究\n", + "The Algebraic Mind: Integrating Connectionism and Cognitive Science (Learning, Development, and Conceptual Change)\n", + "统计机器学习导论\n", + "赛先生的梦魇: 新技术革命二十讲\n", + "TensorFlow技术解析与实战\n", + "企业人工智能战略\n", + "逻辑的引擎\n", + "The Age of Spiritual Machines: When Computers Exceed Human Intelligence\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=400&type=T\n", + "Python机器学习经典实例\n", + "Python数据科学与机器学习\n", + "精通Visual C++指纹模式识别系统算法及实现\n", + "迷人的技术\n", + "Race Against the Machine: How the Digital Revolution is Accelerating Innovation, Driving Productivity, and Irreversibly Tr\n", + "神经网络与深度学习\n", + "On Intelligence: How a New Understanding of the Brain will Lead to the Creation of Truly Intelligent Machines\n", + "身体的智能: 智能科学新视角\n", + "大数据智能: 互联网时代的机器学习和自然语言处理技术\n", + "The New Division of Labor: How Computers Are Creating the Next Job Market\n", + "解析深度学习:语音识别实践\n", + "一本书读懂人工智能\n", + "如何求解问题: 现代启发式方法\n", + "第四次教育革命: 人工智能如何改变教育\n", + "The AI Delusion\n", + "The Mind's I: Fantasies And Reflections On Self & Soul\n", + "智能摄影测量学导论\n", + "让法律人读懂人工智能\n", + "Neural Networks and Statistical Learning\n", + "Neural Networks and Learning Machines: Third Edition\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=420&type=T\n", + "内容算法: 把内容变成价值的效率系统\n", + "复杂的引擎\n", + "人工智能导论\n", + "超级思维: 人类和计算机一起思考的惊人力量\n", + "Talking Nets\n", + "计算机程序的构造和解释: 原书第2版\n", + "Memory and the Computational Brain: Why Cognitive Science will Transform Neuroscience\n", + "Matrix Computations\n", + "The Philosophy of Artificial Intelligence\n", + "人工智能会取代人类吗?: 智能时代的人类未来\n", + "机器学习在线:解析阿里云机器学习平台\n", + "人有人的用处: 控制论与社会\n", + "必然\n", + "通信与移动系统\n", + "新版机器人技术手册\n", + "推荐系统: 技术、评估及高效算法\n", + "人工智能的冲击: 失去工作,还是不用工作?\n", + "计算机和人脑\n", + "香农传: 从0到1开创信息时代\n", + "大数据架构商业之路: 从业务需求到技术方案\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=440&type=T\n", + "深入理解XGBoost:高效机器学习算法与进阶\n", + "Deep Medicine: How Artificial Intelligence Can Make Healthcare Human Again\n", + "深度强化学习: 原理与实践\n", + "克隆版大脑\n", + "聊天机器人:对话式体验产品设计\n", + "Neural-Symbolic Cognitive Reasoning\n", + "统计之美: 人工智能时代的科学思维\n", + "超人类革命: 生物科技将如何改变我们的未来?\n", + "机器翻译简明教程: 翻译专业本科生系列教材\n", + "Probably Approximately Correct: Nature’s Algorithms for Learning and Prospering in a Complex World\n", + "从掷骰子到阿尔法狗:趣谈概率\n", + "智能驾驶技术:路径规划与导航控制\n", + "计算智能导论\n", + "Python机器学习(原书第2版)\n", + "三体智能革命\n", + "计算机科学中的数学: 信息与智能时代的必修课\n", + "中国城市大洗牌\n", + "人工智能革命: 历史、当下与未来\n", + "AI的25种可能\n", + "玩具\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=460&type=T\n", + "数据挖掘导论\n", + "深度学习与计算机视觉: 算法原理、框架应用与代码实现\n", + "Reinforcement Learning: An Introduction\n", + "Life 3.0: Being Human in the Age of Artificial Intelligence\n", + "Machine Learning in Action\n", + "I Am a Strange Loop\n", + "反常识\n", + "The Future of the Mind: The Scientific Quest to Understand, Enhance, and Empower the Mind\n", + "2030年の世界地図帳: あたらしい経済とSDGs、未来への展望\n", + "2030·终点镇\n", + "心我论: 对自我和灵魂的奇思冥想\n", + "5G+AI智能商业:商业变革和产业机遇\n", + "人工智能学院本硕博培养体系\n", + "Artificial Intelligence (3rd Edition)\n", + "AI世代生存哲學大思考: 人人都必須了解的「新AI學」\n", + "The Zero Marginal Cost Society: The Internet of Things, the Collaborative Commons, and the Eclipse of Capitalism\n", + "Hello World: How to be Human in the Age of the Machine\n", + "Learning with Kernels: Support Vector Machines, Regularization, Optimization, and Beyond (Adaptive Computation and Mach\n", + "The Creativity Code: Art and Innovation in the Age of AI\n", + "Abstraction in Artificial Intelligence and Complex Systems\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=480&type=T\n", + "Python深度学习: 用Python快速学习深度神经网络\n", + "人类帝国的覆灭: 一个机器人的回忆录\n", + "Statistical Rethinking: A Bayesian Course with Examples in R and Stan\n", + "用户的本质: 数字化时代的精准运营法则\n", + "人工智能导论\n", + "未来地图: 创造人工智能万亿级产业的商业模式和路径\n", + "Keras快速上手:基于Python的深度学习实战\n", + "Feature Selection for High-Dimensional Data (Artificial Intelligence: Foundations, Theory, and Algorithms)\n", + "万物重构:智能社会来临前夜的思索\n", + "未来之路: 科技、商业和人类的选择\n", + "大脑、机器和数学\n", + "人工智能的进化: 计算机思维离人类心智还有多远\n", + "Programming Collective Intelligence: Building Smart Web 2.0 Applications\n", + "Handbook of Research on Synthesizing Human Emotion in Intelligent Systems and Robotics(智能系统与机器人技术的合成人类情感研究手册(丛书))\n", + "微表情心理学: 读心识人准到骨子\n", + "海伯利安\n", + "Introduction to Bayesian Scientific Computing: Ten Lectures on Subjective Computing (Surveys and Tutorials in the Applied Mathematical Sciences\n", + "机器人战争: 21世纪机器人技术革命与反思\n", + "认知神经科学: 关于心智的生物学\n", + "算法小时代: 从数学到生活的历变\n", + "https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start=500&type=T\n", + "Computer Vision: Algorithms and Applications\n", + "Darwin among the Machines: The Evolution of Global Intelligence\n", + "The Most Human Human: What Talking with Computers Teaches Us About What It Means to Be Alive\n", + "失控: 全人类的最终命运和结局\n", + "人类简史: 从动物到上帝\n" + ] + } + ], + "source": [ + "import re\n", + "import time\n", + "\n", + "page_id = 1\n", + "last_start = 0\n", + "while 1:\n", + " start_id = 20 * (page_id - 1)\n", + " url = 'https://book.douban.com/tag/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD?start={}&type=T'.format(start_id)\n", + " print(url)\n", + " content = douban_crawler.download(url)\n", + " tree = html.fromstring(content)\n", + " if page_id == 1:\n", + " page_links = tree.xpath(\"//div[@class='paginator']/a[last()]/@href\")\n", + " if page_links:\n", + " last_start = int(re.findall('start=(\\d+)', page_links[0])[0])\n", + " print('Last Start ID: ', last_start)\n", + " book_infos = tree.xpath(\"//li[@class='subject-item']\")\n", + " for book_info in book_infos:\n", + " book_name_elem = book_info.xpath('.//h2/a')[0]\n", + " book_name = re.sub('\\s{2,}', '', book_name_elem.text_content().replace('\\n', ''))\n", + " book_url = book_name_elem.attrib['href']\n", + " book_pub_info = book_info.xpath(\".//div[@class='pub']\")[0].text.strip()\n", + " book_intro = 'N/A'\n", + " book_intro_elem = book_info.xpath(\".//div[@class='info']/p\")\n", + " if book_intro_elem:\n", + " book_intro = book_intro_elem[0].text.strip()\n", + " print(book_name)\n", + " page_id += 1\n", + " if start_id == last_start:\n", + " break\n", + " time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Python深度学习: 用Python快速学习深度神经网络 '" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "re.sub('\\s{2,}', '', 'Python深度学习 : 用Python快速学习深度神经网络 ')" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "s = '/tag/神经网络888?start=20&type=T'" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'20'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "re.findall('start=(\\d+)', s)[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'20'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s[s.index('start=')+6:-7]" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s.index('start=')" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "18" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s.index('&type')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 67688f95781d7fc52ed8e7e5473042c69bcaa876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年6月12日 19:47:11 +0800 Subject: [PATCH 09/13] QA 15 added --- README.md | 1 + questions/question_015.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 questions/question_015.md diff --git a/README.md b/README.md index 48a5eb5..432ff2a 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ | 2020年6月5日 | 第14讲:爬虫进阶之DOM树与XPath
摘要:DOM的基本概念,DOM树的基本概念,XPath的概念和基本语法,Chrome里XPath Helper扩展的使用,特定目标XPath的获取和精简,用lxml库实现网页源码的解析和XPath目标定位,基于XPath的页面信息分层抽取。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_14.ipynb) | [L14.1](https://www.bilibili.com/video/BV1b7411N7P2?p=34) | | - | 第14讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_014.md))
摘要:如何深入了解xpath、xpath能否完全代替正则表达式、大爬虫也需要对每个网页配置抽取表达式吗、访问图片时拒绝访问如何处理、xpath里的@href什么意思、xpath的绝对路径和相对路径有何区别、DOM树与C++的树一样吗、xpath与正则表达式适用场景如何效率比较及怎样选择、遇到具体变成问题怎么找解决方案、xpath helper安装不了怎么办、lxml解析为什么要解码、表格数据如何采集、DOM和xpath的关系、pycharm怎么安装lxml、爬虫在生活中的应用、豆瓣书名副标题的采集问题、包含子节点的节点如何获取全部文本、xpath能否用于普通字符串、beautifulsoup和lxml在解析方面有什么区别吗、python能提供网页服务吗、模型到底是什么、没有插件如何快速获取xpath等。 | [L14.2](https://www.bilibili.com/video/BV1b7411N7P2?p=35) | | 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。 | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | +| - | 第15讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_015.md))
摘要:如何采集音乐网站并播放音乐、豆瓣爬虫能否为书做个类、翻页能否从最后往前翻、urllib库为什么没提供urldecode函数、采集的数据用什么形式存比较好、为什么翻页经常是start=0/20/40而不是page=1、搜索引擎也是爬虫吗、能否用正则实现翻页信息采集、采集信息不全时的解决思路、页面跳转如何采集、怎样将数据方便导入Excel、爬虫 vs. 镜像、做爬虫会违法吗、动态网页或局部刷新网页的爬取、爬虫翻页没有尾页的处理方式、这是最后一节课吗...... | [L15.2](https://www.bilibili.com/video/BV1b7411N7P2?p=37) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/questions/question_015.md b/questions/question_015.md new file mode 100644 index 0000000..4233519 --- /dev/null +++ b/questions/question_015.md @@ -0,0 +1,29 @@ +| 第15讲答疑 问题列表 | +|--------------| +|是否可以实现让程序自己访问音乐网站然后播放里面的音乐?| +|encoding要加url才能搜出来吗?| +|爬虫过程中是否可以把书变成一个类,将每次采集到的信息存入一个书类中,再来可以对书籍进行分类排序等等操作| +|能从最后一页向第一页翻吗| +|urllib库为什么不提供urldecode函数| +|爬到的数据该怎样储存好?是用txt还是其他的档案?| +|想知道为什么网址中页数会是start=0、20、40这种start=20(page_id-1)的规律,而不是0、1、2这样的呢?是有什么特殊的意义吗?| +|搜索引擎的原理也是爬虫吗,为什么我的爬虫运行起来很慢,而搜索引擎可以秒出结果| +|怎么把收集到的数字信息做成一个表或者图形?| +|所有由中文编码出来的串与网站url中的串都是相同的吗| +|请问正则表达式能否也能实现类似翻页采集信息的功能呢?| +|读取神经网络类所有图书的时候,发现信息不全的情况以后,老师是如何想到其他的办法去取数据的| +|网页发生了页面跳转可以用爬虫提取内容么| +|采集了很多数据,但比较乱,有没有什么快捷的方式将这些数据整理到Excel里面?| +|las还有其的使用吗?| +|爬虫运行的实际上是搜索以及复制粘贴的过程,那是否可以直接镜像复制该网站,并提高运行速度。| +|翻页的操作是否可以一次同时获取几个页面的数据?就是一次输入几个页码,然后这几页的数据就同时出现| +|目前公安实际情况中,对爬虫违法的界限是什么?爬虫从本质上就是更快速的手速,为什么会违法?| +|怎么爬取动态变化的网页| +|如果跳转页面里面还有链接,爬虫能读取里面的内容吗| +|如何翻页爬取url不变的网站| +|如何通过爬虫建立一个简单的搜索引擎?| +|encode其他使用| +|可以像小程序那样url接其他后端链接吗| +|所有含页码网页都有start=吗| +|请问老师,爬虫翻页的时候它没有给出尾页怎么办 那也没法判断终止啊| +|这是最后一节课吗?下学期还会有你的python选修吗?| \ No newline at end of file From 0a349a9898506b730985a4f106f4239d52990ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年6月19日 07:10:47 +0800 Subject: [PATCH 10/13] Class 16 added --- README.md | 1 + code/Python_Class_16.ipynb | 414 +++++++++++++++++++++++++++++++++++++ 2 files changed, 415 insertions(+) create mode 100644 code/Python_Class_16.ipynb diff --git a/README.md b/README.md index 432ff2a..a902a28 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ | - | 第14讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_014.md))
摘要:如何深入了解xpath、xpath能否完全代替正则表达式、大爬虫也需要对每个网页配置抽取表达式吗、访问图片时拒绝访问如何处理、xpath里的@href什么意思、xpath的绝对路径和相对路径有何区别、DOM树与C++的树一样吗、xpath与正则表达式适用场景如何效率比较及怎样选择、遇到具体变成问题怎么找解决方案、xpath helper安装不了怎么办、lxml解析为什么要解码、表格数据如何采集、DOM和xpath的关系、pycharm怎么安装lxml、爬虫在生活中的应用、豆瓣书名副标题的采集问题、包含子节点的节点如何获取全部文本、xpath能否用于普通字符串、beautifulsoup和lxml在解析方面有什么区别吗、python能提供网页服务吗、模型到底是什么、没有插件如何快速获取xpath等。 | [L14.2](https://www.bilibili.com/video/BV1b7411N7P2?p=35) | | 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。 | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | | - | 第15讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_015.md))
摘要:如何采集音乐网站并播放音乐、豆瓣爬虫能否为书做个类、翻页能否从最后往前翻、urllib库为什么没提供urldecode函数、采集的数据用什么形式存比较好、为什么翻页经常是start=0/20/40而不是page=1、搜索引擎也是爬虫吗、能否用正则实现翻页信息采集、采集信息不全时的解决思路、页面跳转如何采集、怎样将数据方便导入Excel、爬虫 vs. 镜像、做爬虫会违法吗、动态网页或局部刷新网页的爬取、爬虫翻页没有尾页的处理方式、这是最后一节课吗...... | [L15.2](https://www.bilibili.com/video/BV1b7411N7P2?p=37) | +| 2020年6月19日 | 第16讲:多级采集与多线程
摘要:标签采集与图书列表也采集结合的嵌套二级采集,多线程编程的相关概念:进程、线程、同步/异步、阻塞式/非阻塞式、线程池等,用concurrent.futures标准库实现多线程并行采集。 | [L16.1](https://www.bilibili.com/video/BV1b7411N7P2?p=38) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/code/Python_Class_16.ipynb b/code/Python_Class_16.ipynb new file mode 100644 index 0000000..5eaf3d2 --- /dev/null +++ b/code/Python_Class_16.ipynb @@ -0,0 +1,414 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "url = 'https://book.douban.com/tag/?view=type'\n", + "content = douban_crawler.download(url)\n", + "tree = html.fromstring(content)\n", + "tags = tree.xpath(\"//td/a/text()\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'%E5%B0%8F%E8%AF%B4'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urllib.parse.quote(tags[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current tag: 小说\n", + "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T\n", + "Last Start ID: 7600\n", + "活着\n", + "房思琪的初恋乐园\n", + "白夜行\n", + "解忧杂货店\n", + "红楼梦\n", + "追风筝的人\n", + "百年孤独\n", + "小王子\n", + "围城\n", + "平凡的世界(全三部)\n", + "嫌疑人X的献身\n", + "霍乱时期的爱情\n", + "1984\n", + "飘\n", + "月亮与六便士\n", + "三体: "地球往事"三部曲之一\n", + "三体全集: 地球往事三部曲\n", + "局外人\n", + "杀死一只知更鸟\n", + "骆驼祥子\n", + "------------------------------------\n", + "Current tag: 外国文学\n", + "https://book.douban.com/tag/%E5%A4%96%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "小王子\n", + "追风筝的人\n", + "百年孤独\n", + "飘\n", + "1984\n", + "霍乱时期的爱情\n", + "月亮与六便士\n", + "月亮和六便士\n", + "杀死一只知更鸟\n", + "傲慢与偏见\n", + "局外人\n", + "动物农场\n", + "安徒生童话故事集\n", + "简爱(英文全本)\n", + "老人与海\n", + "基督山伯爵\n", + "哈利•波特\n", + "一个陌生女人的来信\n", + "牧羊少年奇幻之旅\n", + "肖申克的救赎\n", + "------------------------------------\n", + "Current tag: 文学\n", + "https://book.douban.com/tag/%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "你当像鸟飞往你的山\n", + "房思琪的初恋乐园\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "追风筝的人\n", + "围城\n", + "活着\n", + "平凡的世界(全三部)\n", + "解忧杂货店\n", + "撒哈拉的故事\n", + "霍乱时期的爱情\n", + "月亮和六便士\n", + "1984\n", + "边城\n", + "局外人\n", + "许三观卖血记\n", + "白鹿原: 20周年精装典藏版\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "云边有个小卖部\n", + "------------------------------------\n", + "Current tag: 经典\n", + "https://book.douban.com/tag/%E7%BB%8F%E5%85%B8?start=0&type=T\n", + "Last Start ID: 7820\n", + "活着\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "围城\n", + "飘\n", + "平凡的世界(全三部)\n", + "三体全集: 地球往事三部曲\n", + "骆驼祥子\n", + "月亮与六便士\n", + "哈利•波特\n", + "杀死一只知更鸟\n", + "霍乱时期的爱情\n", + "傲慢与偏见\n", + "1984\n", + "追风筝的人\n", + "边城\n", + "安徒生童话故事集\n", + "围城\n", + "白鹿原: 20周年精装典藏版\n", + "------------------------------------\n", + "Current tag: 中国文学\n", + "https://book.douban.com/tag/%E4%B8%AD%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7720\n", + "活着\n", + "围城\n", + "平凡的世界(全三部)\n", + "骆驼祥子\n", + "边城\n", + "城南旧事: 纪念普及版\n", + "明朝那些事儿(1-9): 限量版\n", + "撒哈拉的故事\n", + "红楼梦\n", + "白鹿原: 20周年精装典藏版\n", + "许三观卖血记\n", + "三体全集: 地球往事三部曲\n", + "呐喊\n", + "房思琪的初恋乐园\n", + "平凡的世界\n", + "围城\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "许三观卖血记\n", + "朝花夕拾\n", + "人生海海\n", + "------------------------------------\n" + ] + } + ], + "source": [ + "import re\n", + "import time\n", + "import requests\n", + "from lxml import html\n", + "import urllib.parse\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "tag_list_url = 'https://book.douban.com/tag/?view=type'\n", + "tag_content = douban_crawler.download(tag_list_url)\n", + "tag_tree = html.fromstring(tag_content)\n", + "tags = tag_tree.xpath(\"//td/a/text()\")\n", + "for tag in tags[:5]:\n", + " print('Current tag:', tag)\n", + " tag = urllib.parse.quote(tag)\n", + " page_id = 1\n", + " last_start = 0\n", + " while 1:\n", + " start_id = 20 * (page_id - 1)\n", + " url = 'https://book.douban.com/tag/{}?start={}&type=T'.format(tag, start_id)\n", + " print(url)\n", + " content = douban_crawler.download(url)\n", + " tree = html.fromstring(content)\n", + " if page_id == 1:\n", + " page_links = tree.xpath(\"//div[@class='paginator']/a[last()]/@href\")\n", + " if page_links:\n", + " last_start = int(re.findall('start=(\\d+)', page_links[0])[0])\n", + " print('Last Start ID: ', last_start)\n", + " book_infos = tree.xpath(\"//li[@class='subject-item']\")\n", + " for book_info in book_infos:\n", + " book_name_elem = book_info.xpath('.//h2/a')[0]\n", + " book_name = re.sub('\\s{2,}', '', book_name_elem.text_content().replace('\\n', ''))\n", + " book_url = book_name_elem.attrib['href']\n", + " book_pub_info = book_info.xpath(\".//div[@class='pub']\")[0].text.strip()\n", + " book_intro = 'N/A'\n", + " book_intro_elem = book_info.xpath(\".//div[@class='info']/p\")\n", + " if book_intro_elem:\n", + " book_intro = book_intro_elem[0].text.strip()\n", + " print(book_name)\n", + " page_id += 1\n", + " if start_id == last_start:\n", + " break\n", + " print('------------------------------------')\n", + " break\n", + " time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "urls = [f'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start={start_id}&type=T' for start_id in range(0, 200, 20)]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urls" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "Wall time: 1.11 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "import requests\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "# Retrieve a single page and report the URL and contents\n", + "def load_url(url):\n", + " global douban_crawler\n", + " return douban_crawler.download(url)\n", + "\n", + "# We can use a with statement to ensure threads are cleaned up promptly\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_url = {executor.submit(load_url, url): url for url in urls}\n", + " for future in concurrent.futures.as_completed(future_to_url):\n", + " url = future_to_url[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s' % (url, exc))\n", + " else:\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "Wall time: 2.69 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "for url in urls:\n", + " data = douban_crawler.download(url)\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 8db316d5d372cf0bb315b5485c3b7cc5627113eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: 2020年6月21日 17:19:30 +0800 Subject: [PATCH 11/13] QA 16 addef --- README.md | 1 + questions/question_016.md | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 questions/question_016.md diff --git a/README.md b/README.md index a902a28..3e45268 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ | 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。 | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | | - | 第15讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_015.md))
摘要:如何采集音乐网站并播放音乐、豆瓣爬虫能否为书做个类、翻页能否从最后往前翻、urllib库为什么没提供urldecode函数、采集的数据用什么形式存比较好、为什么翻页经常是start=0/20/40而不是page=1、搜索引擎也是爬虫吗、能否用正则实现翻页信息采集、采集信息不全时的解决思路、页面跳转如何采集、怎样将数据方便导入Excel、爬虫 vs. 镜像、做爬虫会违法吗、动态网页或局部刷新网页的爬取、爬虫翻页没有尾页的处理方式、这是最后一节课吗...... | [L15.2](https://www.bilibili.com/video/BV1b7411N7P2?p=37) | | 2020年6月19日 | 第16讲:多级采集与多线程
摘要:标签采集与图书列表也采集结合的嵌套二级采集,多线程编程的相关概念:进程、线程、同步/异步、阻塞式/非阻塞式、线程池等,用concurrent.futures标准库实现多线程并行采集。 | [L16.1](https://www.bilibili.com/video/BV1b7411N7P2?p=38) | +| | 第16讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_016.md))
摘要:GIL是什么、为什么线程池适用于IO密集型场景而进程池适用于计算密集型场景、多进程有什么实际应用、爬着爬着就什么也采集不到了是被发现了吗、为什么多线程能提高运行速度、二级列表很多页的时候怎么设置采集规则、线程池用完变空后还会占内存吗、豆瓣爬虫会限制爬取信息的数量么、多线程方式采集的上限取决于什么、如何确定爬虫程序最优线程个数、多线程采集如何保留项目在原页面的顺序信息等。 | [L16.2](https://www.bilibili.com/video/BV1b7411N7P2?p=39) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/questions/question_016.md b/questions/question_016.md new file mode 100644 index 0000000..1656366 --- /dev/null +++ b/questions/question_016.md @@ -0,0 +1,13 @@ +| 第16讲答疑 问题列表 | +|--------------| +|python GIL锁是什么,导致线程池适用于IO密集型场景,而进程池适用于计算密集型场景| +|多进程有什么实际应用?| +|老师,我的爬虫在今天前一段时间是可以爬到东西的,但后面爬着爬着就什么也采集不到了,我这是被发现了吗?| +|还是不是很理解为什么多线程能提高运行速度,CPU每次不是只能执行一条指令嘛?| +|二级列表很多页的时候怎么设置采集规则| +|即来即用,那么如果用完变空后,要占内存吗?像动态申请吗?| +|老师您好,豆瓣爬虫会限制爬去信息的数量么,
爬取的内容最多只有400条| +|两个集合取并集,内容确实去重了,为什么检查长度的时候还是显示两个集合的长度直接相加呢| +|请问老师,采用多线程的方式和原有方式相比,是不是可以理解为用内存换时间的一种方式?
多线程方式采集的上限取决于什么呢?| +|进程池里面进程数量是否限制?如何确定某个爬虫程序中最优进程个数或者说最优进程个数与哪些因素有关,如何测试| +|想到一个问题,书签是相互独立的,多线程采抽存没问题。单个标签下,书有排名,多线程的话,可能后面页数抽取的内容会比前面页数的内容先被写进文件,会打乱原有的顺序。| \ No newline at end of file From 390d0de72730dc56c716dc78ae70b691ec8cf9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: Thu, 2 Jul 2020 22:01:49 +0800 Subject: [PATCH 12/13] Class 17 added --- README.md | 5 +- code/Python_Class_17.ipynb | 562 +++++++++++++++++++++++++++++++++++++ 2 files changed, 565 insertions(+), 2 deletions(-) create mode 100644 code/Python_Class_17.ipynb diff --git a/README.md b/README.md index 3e45268..312d511 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,11 @@ | - | 第13讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_013.md))
摘要:编程状态不好时该怎么办、课下自己调试感觉困难怎么办、如何收集股票信息并用图表分析、数据的爬取加可视化、遍历过程中为什么不建议修改遍历序列、爬虫在工作中的实例、爬虫的个性化与爬虫基类的重载、除正则表达式以外还有什么其他方式可以解析网页、有些网页加载过程中有多个doc文件该如何处理、批量爬取爬虫的架构、课上的爬虫离商业爬虫有多远、分割文本的爬取有什么高效办法、如何爬取某具体方向的内容、为什么会有乱码。 | [L13.2](https://www.bilibili.com/video/av92186118?p=33) | | 2020年6月5日 | 第14讲:爬虫进阶之DOM树与XPath
摘要:DOM的基本概念,DOM树的基本概念,XPath的概念和基本语法,Chrome里XPath Helper扩展的使用,特定目标XPath的获取和精简,用lxml库实现网页源码的解析和XPath目标定位,基于XPath的页面信息分层抽取。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_14.ipynb) | [L14.1](https://www.bilibili.com/video/BV1b7411N7P2?p=34) | | - | 第14讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_014.md))
摘要:如何深入了解xpath、xpath能否完全代替正则表达式、大爬虫也需要对每个网页配置抽取表达式吗、访问图片时拒绝访问如何处理、xpath里的@href什么意思、xpath的绝对路径和相对路径有何区别、DOM树与C++的树一样吗、xpath与正则表达式适用场景如何效率比较及怎样选择、遇到具体变成问题怎么找解决方案、xpath helper安装不了怎么办、lxml解析为什么要解码、表格数据如何采集、DOM和xpath的关系、pycharm怎么安装lxml、爬虫在生活中的应用、豆瓣书名副标题的采集问题、包含子节点的节点如何获取全部文本、xpath能否用于普通字符串、beautifulsoup和lxml在解析方面有什么区别吗、python能提供网页服务吗、模型到底是什么、没有插件如何快速获取xpath等。 | [L14.2](https://www.bilibili.com/video/BV1b7411N7P2?p=35) | -| 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。 | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | +| 2020年6月12日 | 第15讲:翻页的爬取和采集目标分析方法
摘要:翻页链接的获取思路、末尾页链接的检测、程序的迭代改进、从解决问题的角度思考编程过程、培养对程序的"审美"、对特殊情况的推演思路、重用与可读性、url encode/quote的使用、对网站数据可用性和扩展渠道的考察。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_15.ipynb) | [L15.1](https://www.bilibili.com/video/BV1b7411N7P2?p=36) | | - | 第15讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_015.md))
摘要:如何采集音乐网站并播放音乐、豆瓣爬虫能否为书做个类、翻页能否从最后往前翻、urllib库为什么没提供urldecode函数、采集的数据用什么形式存比较好、为什么翻页经常是start=0/20/40而不是page=1、搜索引擎也是爬虫吗、能否用正则实现翻页信息采集、采集信息不全时的解决思路、页面跳转如何采集、怎样将数据方便导入Excel、爬虫 vs. 镜像、做爬虫会违法吗、动态网页或局部刷新网页的爬取、爬虫翻页没有尾页的处理方式、这是最后一节课吗...... | [L15.2](https://www.bilibili.com/video/BV1b7411N7P2?p=37) | -| 2020年6月19日 | 第16讲:多级采集与多线程
摘要:标签采集与图书列表也采集结合的嵌套二级采集,多线程编程的相关概念:进程、线程、同步/异步、阻塞式/非阻塞式、线程池等,用concurrent.futures标准库实现多线程并行采集。 | [L16.1](https://www.bilibili.com/video/BV1b7411N7P2?p=38) | +| 2020年6月19日 | 第16讲:多级采集与多线程
摘要:标签采集与图书列表也采集结合的嵌套二级采集,多线程编程的相关概念:进程、线程、同步/异步、阻塞式/非阻塞式、线程池等,用concurrent.futures标准库实现多线程并行采集。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_16.ipynb) | [L16.1](https://www.bilibili.com/video/BV1b7411N7P2?p=38) | | | 第16讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_016.md))
摘要:GIL是什么、为什么线程池适用于IO密集型场景而进程池适用于计算密集型场景、多进程有什么实际应用、爬着爬着就什么也采集不到了是被发现了吗、为什么多线程能提高运行速度、二级列表很多页的时候怎么设置采集规则、线程池用完变空后还会占内存吗、豆瓣爬虫会限制爬取信息的数量么、多线程方式采集的上限取决于什么、如何确定爬虫程序最优线程个数、多线程采集如何保留项目在原页面的顺序信息等。 | [L16.2](https://www.bilibili.com/video/BV1b7411N7P2?p=39) | +| | 第17讲、深入探索多线程
摘要:多线程的调度顺序,原子操作的概念,f"{}"字符串简化格式化的用法,print默认参数的"秘密",信号量的概念,用信号量保证"原子操作",非定向爬虫的概念,搜索引擎的基本原理。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_17.ipynb) | [L17.1](https://www.bilibili.com/video/BV1b7411N7P2?p=40) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/code/Python_Class_17.ipynb b/code/Python_Class_17.ipynb new file mode 100644 index 0000000..4d05e71 --- /dev/null +++ b/code/Python_Class_17.ipynb @@ -0,0 +1,562 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "url = 'https://book.douban.com/tag/?view=type'\n", + "content = douban_crawler.download(url)\n", + "tree = html.fromstring(content)\n", + "tags = tree.xpath(\"//td/a/text()\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'%E5%B0%8F%E8%AF%B4'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urllib.parse.quote(tags[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current tag: 小说\n", + "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T\n", + "Last Start ID: 7600\n", + "活着\n", + "房思琪的初恋乐园\n", + "白夜行\n", + "解忧杂货店\n", + "红楼梦\n", + "追风筝的人\n", + "百年孤独\n", + "小王子\n", + "围城\n", + "平凡的世界(全三部)\n", + "嫌疑人X的献身\n", + "霍乱时期的爱情\n", + "1984\n", + "飘\n", + "月亮与六便士\n", + "三体: "地球往事"三部曲之一\n", + "三体全集: 地球往事三部曲\n", + "局外人\n", + "杀死一只知更鸟\n", + "骆驼祥子\n", + "------------------------------------\n", + "Current tag: 外国文学\n", + "https://book.douban.com/tag/%E5%A4%96%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "小王子\n", + "追风筝的人\n", + "百年孤独\n", + "飘\n", + "1984\n", + "霍乱时期的爱情\n", + "月亮与六便士\n", + "月亮和六便士\n", + "杀死一只知更鸟\n", + "傲慢与偏见\n", + "局外人\n", + "动物农场\n", + "安徒生童话故事集\n", + "简爱(英文全本)\n", + "老人与海\n", + "基督山伯爵\n", + "哈利•波特\n", + "一个陌生女人的来信\n", + "牧羊少年奇幻之旅\n", + "肖申克的救赎\n", + "------------------------------------\n", + "Current tag: 文学\n", + "https://book.douban.com/tag/%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "你当像鸟飞往你的山\n", + "房思琪的初恋乐园\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "追风筝的人\n", + "围城\n", + "活着\n", + "平凡的世界(全三部)\n", + "解忧杂货店\n", + "撒哈拉的故事\n", + "霍乱时期的爱情\n", + "月亮和六便士\n", + "1984\n", + "边城\n", + "局外人\n", + "许三观卖血记\n", + "白鹿原: 20周年精装典藏版\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "云边有个小卖部\n", + "------------------------------------\n", + "Current tag: 经典\n", + "https://book.douban.com/tag/%E7%BB%8F%E5%85%B8?start=0&type=T\n", + "Last Start ID: 7820\n", + "活着\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "围城\n", + "飘\n", + "平凡的世界(全三部)\n", + "三体全集: 地球往事三部曲\n", + "骆驼祥子\n", + "月亮与六便士\n", + "哈利•波特\n", + "杀死一只知更鸟\n", + "霍乱时期的爱情\n", + "傲慢与偏见\n", + "1984\n", + "追风筝的人\n", + "边城\n", + "安徒生童话故事集\n", + "围城\n", + "白鹿原: 20周年精装典藏版\n", + "------------------------------------\n", + "Current tag: 中国文学\n", + "https://book.douban.com/tag/%E4%B8%AD%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7720\n", + "活着\n", + "围城\n", + "平凡的世界(全三部)\n", + "骆驼祥子\n", + "边城\n", + "城南旧事: 纪念普及版\n", + "明朝那些事儿(1-9): 限量版\n", + "撒哈拉的故事\n", + "红楼梦\n", + "白鹿原: 20周年精装典藏版\n", + "许三观卖血记\n", + "三体全集: 地球往事三部曲\n", + "呐喊\n", + "房思琪的初恋乐园\n", + "平凡的世界\n", + "围城\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "许三观卖血记\n", + "朝花夕拾\n", + "人生海海\n", + "------------------------------------\n" + ] + } + ], + "source": [ + "import re\n", + "import time\n", + "import requests\n", + "from lxml import html\n", + "import urllib.parse\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "tag_list_url = 'https://book.douban.com/tag/?view=type'\n", + "tag_content = douban_crawler.download(tag_list_url)\n", + "tag_tree = html.fromstring(tag_content)\n", + "tags = tag_tree.xpath(\"//td/a/text()\")\n", + "for tag in tags[:5]:\n", + " print('Current tag:', tag)\n", + " tag = urllib.parse.quote(tag)\n", + " page_id = 1\n", + " last_start = 0\n", + " while 1:\n", + " start_id = 20 * (page_id - 1)\n", + " url = 'https://book.douban.com/tag/{}?start={}&type=T'.format(tag, start_id)\n", + " print(url)\n", + " content = douban_crawler.download(url)\n", + " tree = html.fromstring(content)\n", + " if page_id == 1:\n", + " page_links = tree.xpath(\"//div[@class='paginator']/a[last()]/@href\")\n", + " if page_links:\n", + " last_start = int(re.findall('start=(\\d+)', page_links[0])[0])\n", + " print('Last Start ID: ', last_start)\n", + " book_infos = tree.xpath(\"//li[@class='subject-item']\")\n", + " for book_info in book_infos:\n", + " book_name_elem = book_info.xpath('.//h2/a')[0]\n", + " book_name = re.sub('\\s{2,}', '', book_name_elem.text_content().replace('\\n', ''))\n", + " book_url = book_name_elem.attrib['href']\n", + " book_pub_info = book_info.xpath(\".//div[@class='pub']\")[0].text.strip()\n", + " book_intro = 'N/A'\n", + " book_intro_elem = book_info.xpath(\".//div[@class='info']/p\")\n", + " if book_intro_elem:\n", + " book_intro = book_intro_elem[0].text.strip()\n", + " print(book_name)\n", + " page_id += 1\n", + " if start_id == last_start:\n", + " break\n", + " print('------------------------------------')\n", + " break\n", + " time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "urls = [f'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start={start_id}&type=T' for start_id in range(0, 200, 20)]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urls" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "Wall time: 1.11 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "import requests\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "# Retrieve a single page and report the URL and contents\n", + "def load_url(url):\n", + " global douban_crawler\n", + " return douban_crawler.download(url)\n", + "\n", + "# We can use a with statement to ensure threads are cleaned up promptly\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_url = {executor.submit(load_url, url): url for url in urls}\n", + " for future in concurrent.futures.as_completed(future_to_url):\n", + " url = future_to_url[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s' % (url, exc))\n", + " else:\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "Wall time: 2.69 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "for url in urls:\n", + " data = douban_crawler.download(url)\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "task 1 step 1\n", + "task 1 step 2\n", + "task 1 step 3\n", + "task 1 completed.\n", + "task 1 return 0.\n", + "task 0 step 1\n", + "task 0 step 2\n", + "task 0 step 3\n", + "task 0 completed.\n", + "task 0 return 0.\n", + "task 5 step 1\n", + "task 5 step 2\n", + "task 5 step 3\n", + "task 5 completed.\n", + "task 5 return 0.\n", + "task 6 step 1\n", + "task 6 step 2\n", + "task 6 step 3\n", + "task 6 completed.\n", + "task 6 return 0.\n", + "task 7 step 1\n", + "task 7 step 2\n", + "task 7 step 3\n", + "task 7 completed.\n", + "task 7 return 0.\n", + "task 8 step 1\n", + "task 8 step 2\n", + "task 8 step 3\n", + "task 8 completed.\n", + "task 8 return 0.\n", + "task 9 step 1\n", + "task 9 step 2\n", + "task 9 step 3\n", + "task 9 completed.\n", + "task 9 return 0.\n", + "task 4 step 1\n", + "task 4 step 2\n", + "task 4 step 3\n", + "task 4 completed.\n", + "task 4 return 0.\n", + "task 2 step 1\n", + "task 2 step 2\n", + "task 2 step 3\n", + "task 2 completed.\n", + "task 2 return 0.\n", + "task 3 step 1\n", + "task 3 step 2\n", + "task 3 step 3\n", + "task 3 completed.\n", + "task 3 return 0.\n", + "Wall time: 20 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "import time\n", + "\n", + "from threading import Semaphore\n", + "\n", + "my_semaphore = Semaphore()\n", + "\n", + "def do_it(tid):\n", + " result = []\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 1\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 2\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 3\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} completed.\\n')\n", + " my_semaphore.acquire()\n", + " print(''.join(result))\n", + " my_semaphore.release()\n", + " return 0\n", + "\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_tid = {executor.submit(do_it, tid): tid for tid in range(10)}\n", + " for future in concurrent.futures.as_completed(future_to_tid):\n", + " tid = future_to_tid[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s.\\n' % (tid, exc), end='')\n", + " else:\n", + " print('task %d return %d.\\n' % (tid, data), end='')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[1;31mDocstring:\u001b[0m\n", + "print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n", + "\n", + "Prints the values to a stream, or to sys.stdout by default.\n", + "Optional keyword arguments:\n", + "file: a file-like object (stream); defaults to the current sys.stdout.\n", + "sep: string inserted between values, default a space.\n", + "end: string appended after the last value, default a newline.\n", + "flush: whether to forcibly flush the stream.\n", + "\u001b[1;31mType:\u001b[0m builtin_function_or_method\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\t2\t31\t2\t31\t2\t3" + ] + } + ], + "source": [ + "print(1,2,3,sep='\\t',end='')\n", + "print(1,2,3,sep='\\t',end='')\n", + "print(1,2,3,sep='\\t',end='')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 1cfc2caa25116930f0f6a3ef05eb4f7894ddfc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=8F=AF=E5=8F=AF-=E7=88=B1=E7=94=9F=E6=B4=BB?= Date: Thu, 9 Jul 2020 21:58:44 +0800 Subject: [PATCH 13/13] class 18 added --- README.md | 1 + code/Python_Class_18.ipynb | 656 +++++++++++++++++++++++++++++++++++++ 2 files changed, 657 insertions(+) create mode 100644 code/Python_Class_18.ipynb diff --git a/README.md b/README.md index 312d511..d2a499c 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ | 2020年6月19日 | 第16讲:多级采集与多线程
摘要:标签采集与图书列表也采集结合的嵌套二级采集,多线程编程的相关概念:进程、线程、同步/异步、阻塞式/非阻塞式、线程池等,用concurrent.futures标准库实现多线程并行采集。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_16.ipynb) | [L16.1](https://www.bilibili.com/video/BV1b7411N7P2?p=38) | | | 第16讲答疑([问题列表](https://github.com/fly51fly/Practical_Python_Programming/blob/master/questions/question_016.md))
摘要:GIL是什么、为什么线程池适用于IO密集型场景而进程池适用于计算密集型场景、多进程有什么实际应用、爬着爬着就什么也采集不到了是被发现了吗、为什么多线程能提高运行速度、二级列表很多页的时候怎么设置采集规则、线程池用完变空后还会占内存吗、豆瓣爬虫会限制爬取信息的数量么、多线程方式采集的上限取决于什么、如何确定爬虫程序最优线程个数、多线程采集如何保留项目在原页面的顺序信息等。 | [L16.2](https://www.bilibili.com/video/BV1b7411N7P2?p=39) | | | 第17讲、深入探索多线程
摘要:多线程的调度顺序,原子操作的概念,f"{}"字符串简化格式化的用法,print默认参数的"秘密",信号量的概念,用信号量保证"原子操作",非定向爬虫的概念,搜索引擎的基本原理。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_17.ipynb) | [L17.1](https://www.bilibili.com/video/BV1b7411N7P2?p=40) | +| 2020年7月10日 | 第18讲、任务队列与多线程
摘要:队列和任务队列的概念和意义,多线程对任务队列的控制,线程池的"静态"线程用法,多线程的细化控制。
代码:[Jupyter Notebook](https://github.com/fly51fly/Practical_Python_Programming/blob/master/code/Python_Class_18.ipynb) | [L18.1](https://www.bilibili.com/video/BV1b7411N7P2?p=41) | 1. [中文 Python 笔记](https://github.com/lijin-THU/notes-python) 2. [千行代码入门Python](https://github.com/xianhu/LearnPython) diff --git a/code/Python_Class_18.ipynb b/code/Python_Class_18.ipynb new file mode 100644 index 0000000..d546fa3 --- /dev/null +++ b/code/Python_Class_18.ipynb @@ -0,0 +1,656 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import re\n", + "\n", + "class MyCrawler:\n", + " def __init__(self, filename):\n", + " self.filename = filename\n", + " self.headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',\n", + " }\n", + " \n", + " def download(self, url):\n", + " r = requests.get(url, headers=self.headers)\n", + " return r.text\n", + " \n", + " def extract(self, content, pattern):\n", + " result = re.findall(pattern, content)\n", + " return result\n", + " \n", + " def save(self, info):\n", + " with open(self.filename, 'a', encoding='utf-8') as f:\n", + " for item in info:\n", + " f.write('|||'.join(item) + '\\n')\n", + " \n", + " def crawl(self, url, pattern, headers=None):\n", + " if headers:\n", + " self.headers.update(headers)\n", + " content = self.download(url)\n", + " info = self.extract(content, pattern)\n", + " self.save(info)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "url = 'https://book.douban.com/tag/?view=type'\n", + "content = douban_crawler.download(url)\n", + "tree = html.fromstring(content)\n", + "tags = tree.xpath(\"//td/a/text()\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'%E5%B0%8F%E8%AF%B4'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urllib.parse.quote(tags[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current tag: 小说\n", + "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T\n", + "Last Start ID: 7600\n", + "活着\n", + "房思琪的初恋乐园\n", + "白夜行\n", + "解忧杂货店\n", + "红楼梦\n", + "追风筝的人\n", + "百年孤独\n", + "小王子\n", + "围城\n", + "平凡的世界(全三部)\n", + "嫌疑人X的献身\n", + "霍乱时期的爱情\n", + "1984\n", + "飘\n", + "月亮与六便士\n", + "三体: "地球往事"三部曲之一\n", + "三体全集: 地球往事三部曲\n", + "局外人\n", + "杀死一只知更鸟\n", + "骆驼祥子\n", + "------------------------------------\n", + "Current tag: 外国文学\n", + "https://book.douban.com/tag/%E5%A4%96%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "小王子\n", + "追风筝的人\n", + "百年孤独\n", + "飘\n", + "1984\n", + "霍乱时期的爱情\n", + "月亮与六便士\n", + "月亮和六便士\n", + "杀死一只知更鸟\n", + "傲慢与偏见\n", + "局外人\n", + "动物农场\n", + "安徒生童话故事集\n", + "简爱(英文全本)\n", + "老人与海\n", + "基督山伯爵\n", + "哈利•波特\n", + "一个陌生女人的来信\n", + "牧羊少年奇幻之旅\n", + "肖申克的救赎\n", + "------------------------------------\n", + "Current tag: 文学\n", + "https://book.douban.com/tag/%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7640\n", + "你当像鸟飞往你的山\n", + "房思琪的初恋乐园\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "追风筝的人\n", + "围城\n", + "活着\n", + "平凡的世界(全三部)\n", + "解忧杂货店\n", + "撒哈拉的故事\n", + "霍乱时期的爱情\n", + "月亮和六便士\n", + "1984\n", + "边城\n", + "局外人\n", + "许三观卖血记\n", + "白鹿原: 20周年精装典藏版\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "云边有个小卖部\n", + "------------------------------------\n", + "Current tag: 经典\n", + "https://book.douban.com/tag/%E7%BB%8F%E5%85%B8?start=0&type=T\n", + "Last Start ID: 7820\n", + "活着\n", + "小王子\n", + "红楼梦\n", + "百年孤独\n", + "围城\n", + "飘\n", + "平凡的世界(全三部)\n", + "三体全集: 地球往事三部曲\n", + "骆驼祥子\n", + "月亮与六便士\n", + "哈利•波特\n", + "杀死一只知更鸟\n", + "霍乱时期的爱情\n", + "傲慢与偏见\n", + "1984\n", + "追风筝的人\n", + "边城\n", + "安徒生童话故事集\n", + "围城\n", + "白鹿原: 20周年精装典藏版\n", + "------------------------------------\n", + "Current tag: 中国文学\n", + "https://book.douban.com/tag/%E4%B8%AD%E5%9B%BD%E6%96%87%E5%AD%A6?start=0&type=T\n", + "Last Start ID: 7720\n", + "活着\n", + "围城\n", + "平凡的世界(全三部)\n", + "骆驼祥子\n", + "边城\n", + "城南旧事: 纪念普及版\n", + "明朝那些事儿(1-9): 限量版\n", + "撒哈拉的故事\n", + "红楼梦\n", + "白鹿原: 20周年精装典藏版\n", + "许三观卖血记\n", + "三体全集: 地球往事三部曲\n", + "呐喊\n", + "房思琪的初恋乐园\n", + "平凡的世界\n", + "围城\n", + "沉默的大多数: 王小波杂文随笔全编\n", + "许三观卖血记\n", + "朝花夕拾\n", + "人生海海\n", + "------------------------------------\n" + ] + } + ], + "source": [ + "import re\n", + "import time\n", + "import requests\n", + "from lxml import html\n", + "import urllib.parse\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "tag_list_url = 'https://book.douban.com/tag/?view=type'\n", + "tag_content = douban_crawler.download(tag_list_url)\n", + "tag_tree = html.fromstring(tag_content)\n", + "tags = tag_tree.xpath(\"//td/a/text()\")\n", + "for tag in tags[:5]:\n", + " print('Current tag:', tag)\n", + " tag = urllib.parse.quote(tag)\n", + " page_id = 1\n", + " last_start = 0\n", + " while 1:\n", + " start_id = 20 * (page_id - 1)\n", + " url = 'https://book.douban.com/tag/{}?start={}&type=T'.format(tag, start_id)\n", + " print(url)\n", + " content = douban_crawler.download(url)\n", + " tree = html.fromstring(content)\n", + " if page_id == 1:\n", + " page_links = tree.xpath(\"//div[@class='paginator']/a[last()]/@href\")\n", + " if page_links:\n", + " last_start = int(re.findall('start=(\\d+)', page_links[0])[0])\n", + " print('Last Start ID: ', last_start)\n", + " book_infos = tree.xpath(\"//li[@class='subject-item']\")\n", + " for book_info in book_infos:\n", + " book_name_elem = book_info.xpath('.//h2/a')[0]\n", + " book_name = re.sub('\\s{2,}', '', book_name_elem.text_content().replace('\\n', ''))\n", + " book_url = book_name_elem.attrib['href']\n", + " book_pub_info = book_info.xpath(\".//div[@class='pub']\")[0].text.strip()\n", + " book_intro = 'N/A'\n", + " book_intro_elem = book_info.xpath(\".//div[@class='info']/p\")\n", + " if book_intro_elem:\n", + " book_intro = book_intro_elem[0].text.strip()\n", + " print(book_name)\n", + " page_id += 1\n", + " if start_id == last_start:\n", + " break\n", + " print('------------------------------------')\n", + " break\n", + " time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "urls = [f'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start={start_id}&type=T' for start_id in range(0, 200, 20)]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T',\n", + " 'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "urls" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "Wall time: 1.11 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "import requests\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "douban_crawler = MyCrawler('douban.txt')\n", + "\n", + "# Retrieve a single page and report the URL and contents\n", + "def load_url(url):\n", + " global douban_crawler\n", + " return douban_crawler.download(url)\n", + "\n", + "# We can use a with statement to ensure threads are cleaned up promptly\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_url = {executor.submit(load_url, url): url for url in urls}\n", + " for future in concurrent.futures.as_completed(future_to_url):\n", + " url = future_to_url[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s' % (url, exc))\n", + " else:\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T' page is 52753 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=20&type=T' page is 52973 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=40&type=T' page is 54058 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=60&type=T' page is 52622 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=80&type=T' page is 52984 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=100&type=T' page is 52683 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=120&type=T' page is 53638 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=140&type=T' page is 54098 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=160&type=T' page is 53460 bytes\n", + "'https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=180&type=T' page is 53970 bytes\n", + "Wall time: 2.69 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "\n", + "# URLS = ['http://www.163.com/',\n", + "# 'http://www.sina.com.cn/',\n", + "# 'http://baidu.com/',\n", + "# 'http://youdao.com/',\n", + "# 'http://bing.com/']\n", + "\n", + "for url in urls:\n", + " data = douban_crawler.download(url)\n", + " print('%r page is %d bytes' % (url, len(data)))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "task 1 step 1\n", + "task 1 step 2\n", + "task 1 step 3\n", + "task 1 completed.\n", + "task 1 return 0.\n", + "task 0 step 1\n", + "task 0 step 2\n", + "task 0 step 3\n", + "task 0 completed.\n", + "task 0 return 0.\n", + "task 5 step 1\n", + "task 5 step 2\n", + "task 5 step 3\n", + "task 5 completed.\n", + "task 5 return 0.\n", + "task 6 step 1\n", + "task 6 step 2\n", + "task 6 step 3\n", + "task 6 completed.\n", + "task 6 return 0.\n", + "task 7 step 1\n", + "task 7 step 2\n", + "task 7 step 3\n", + "task 7 completed.\n", + "task 7 return 0.\n", + "task 8 step 1\n", + "task 8 step 2\n", + "task 8 step 3\n", + "task 8 completed.\n", + "task 8 return 0.\n", + "task 9 step 1\n", + "task 9 step 2\n", + "task 9 step 3\n", + "task 9 completed.\n", + "task 9 return 0.\n", + "task 4 step 1\n", + "task 4 step 2\n", + "task 4 step 3\n", + "task 4 completed.\n", + "task 4 return 0.\n", + "task 2 step 1\n", + "task 2 step 2\n", + "task 2 step 3\n", + "task 2 completed.\n", + "task 2 return 0.\n", + "task 3 step 1\n", + "task 3 step 2\n", + "task 3 step 3\n", + "task 3 completed.\n", + "task 3 return 0.\n", + "Wall time: 20 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "import concurrent.futures\n", + "import time\n", + "\n", + "from threading import Semaphore\n", + "\n", + "my_semaphore = Semaphore()\n", + "\n", + "def do_it(tid):\n", + " result = []\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 1\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 2\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} step 3\\n')\n", + " time.sleep(1)\n", + " result.append(f'task {tid} completed.\\n')\n", + " my_semaphore.acquire()\n", + " print(''.join(result))\n", + " my_semaphore.release()\n", + " return 0\n", + "\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_tid = {executor.submit(do_it, tid): tid for tid in range(10)}\n", + " for future in concurrent.futures.as_completed(future_to_tid):\n", + " tid = future_to_tid[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s.\\n' % (tid, exc), end='')\n", + " else:\n", + " print('task %d return %d.\\n' % (tid, data), end='')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[1;31mDocstring:\u001b[0m\n", + "print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n", + "\n", + "Prints the values to a stream, or to sys.stdout by default.\n", + "Optional keyword arguments:\n", + "file: a file-like object (stream); defaults to the current sys.stdout.\n", + "sep: string inserted between values, default a space.\n", + "end: string appended after the last value, default a newline.\n", + "flush: whether to forcibly flush the stream.\n", + "\u001b[1;31mType:\u001b[0m builtin_function_or_method\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\t2\t31\t2\t31\t2\t3" + ] + } + ], + "source": [ + "print(1,2,3,sep='\\t',end='')\n", + "print(1,2,3,sep='\\t',end='')\n", + "print(1,2,3,sep='\\t',end='')" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "import concurrent.futures\n", + "import time\n", + "from threading import Semaphore" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T processed.\n", + "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T processed.\n", + "task 1 return 1.\n", + "task 4 return 1.\n", + "task 3 return 1.\n", + "task 2 return 1.\n", + "task 0 return 1.\n" + ] + } + ], + "source": [ + "url_queue = ['https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=0&type=T'] * 2\n", + "result_book_info = []\n", + "working_parser_num = 0\n", + "my_semaphore = Semaphore()\n", + "\n", + "def worker(num):\n", + " round_num = 0\n", + " global url_queue, working_parser_num, my_semaphore\n", + " while True:\n", + " url = None\n", + " my_semaphore.acquire()\n", + " if url_queue:\n", + " url = url_queue.pop()\n", + " my_semaphore.release()\n", + " if url:\n", + " working_parser_num += 1\n", + " parser(url)\n", + " working_parser_num -= 1\n", + " print(f\"{url} processed.\\n\", end='')\n", + " elif working_parser_num == 0 and round_num> 0:\n", + " break\n", + " else:\n", + " time.sleep(1)\n", + " round_num += 1\n", + " return 1\n", + "\n", + "def parser(url):\n", + " time.sleep(2)\n", + "\n", + "THREAD_NUM = 5\n", + "with concurrent.futures.ThreadPoolExecutor(max_workers=THREAD_NUM) as executor:\n", + " # Start the load operations and mark each future with its URL\n", + " future_to_tid = {executor.submit(worker, tid): tid for tid in range(THREAD_NUM)}\n", + " for future in concurrent.futures.as_completed(future_to_tid):\n", + " tid = future_to_tid[future]\n", + " try:\n", + " data = future.result()\n", + " except Exception as exc:\n", + " print('%r generated an exception: %s.\\n' % (tid, exc), end='')\n", + " else:\n", + " print('task %d return %d.\\n' % (tid, data), end='')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "worker(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}

AltStyle によって変換されたページ (->オリジナル) /