<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>如何实现网络爬虫 on 重定向学院</title><link>https://itest2025.pages.dev/categories/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/</link><description>Recent content in 如何实现网络爬虫 on 重定向学院</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Tue, 17 Jun 2025 17:29:15 +0800</lastBuildDate><atom:link href="https://itest2025.pages.dev/categories/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/index.xml" rel="self" type="application/rss+xml"/><item><title>爬虫介绍</title><link>https://itest2025.pages.dev/tutorials/27-001-%E7%88%AC%E8%99%AB%E4%BB%8B%E7%BB%8D/</link><pubDate>Mon, 18 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-001-%E7%88%AC%E8%99%AB%E4%BB%8B%E7%BB%8D/</guid><description>&lt;h3 id="什么是爬虫">什么是爬虫&lt;/h3>
&lt;p>爬虫实际上就是采集网络上数据的一段程序，如果把互联网比喻成一个蜘蛛网，那么蜘蛛就是在网上爬来爬去的蜘蛛，爬虫程序通过请求url地址，根据响应的内容进行解析采集数据， 比如：如果响应内容是html，分析dom结构，进行dom解析、或者正则匹配，如果响应内容是xml/json数据，就可以转数据对象，然后对数据进行解析。&lt;/p>
&lt;h3 id="资源视角">资源视角&lt;/h3>
&lt;p>互联网上一切都是资源，比如视频资源，新闻资源等，爬虫实际上就是批量将别人的资源采集下来变成自己的资源的程序。&lt;/p>
&lt;h3 id="爬虫的一些例子">爬虫的一些例子&lt;/h3>
&lt;ul>
&lt;li>从其他网站爬取特定类型的商品信息，然后发布在自己的网上商城里&lt;/li>
&lt;li>从其他网站爬取一些特定图片，展示在自己的网站里&lt;/li>
&lt;li>搜索引擎爬取网站基本信息，收录在自己的搜索结果里&lt;/li>
&lt;/ul>
&lt;h3 id="最简单的爬虫套路">最简单的爬虫套路&lt;/h3>
&lt;ul>
&lt;li>访问1个站点，获取该站点的html代码&lt;/li>
&lt;li>解析html代码，把感兴趣的数据从html代码里分离出来&lt;/li>
&lt;li>保存这些数据&lt;/li>
&lt;/ul>
&lt;h3 id="实际例子">实际例子&lt;/h3>
&lt;p>假设我需要抓取&lt;a href="http://www.itest.info/courses" target="_blank" rel="noopener noreffer ">重定向科技目前开设的所有测试课程&lt;/a>，那么&lt;/p>
&lt;ul>
&lt;li>先访问&lt;a href="http://www.itest.info/courses" target="_blank" rel="noopener noreffer ">所有课程页面&lt;/a>，把html代码拿到&lt;/li>
&lt;li>解析html代码，从里面抠出来课程的名称和详情地址&lt;/li>
&lt;li>保存课程的名称和地址&lt;/li>
&lt;/ul>
&lt;p>这样就可以实现一个最简单的网络爬虫了。&lt;/p>
&lt;h3 id="爬虫对于测试的意义">爬虫对于测试的意义&lt;/h3>
&lt;p>有时候自己去造一些测试数据是很麻烦的事情，这时候我们就可以使用爬虫去获取其他站点的类似数据，对数据进行加工后就可以当测试数据来使用了。&lt;/p>
&lt;h3 id="reference">Reference&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://blog.thankbabe.com/2017/09/25/spider" target="_blank" rel="noopener noreffer ">大话爬虫的基本套路&lt;/a>&lt;/li>
&lt;li>推荐另一个不错的&lt;a href="https://zhuanlan.zhihu.com/p/21479334" target="_blank" rel="noopener noreffer ">python爬虫教程&lt;/a>，应该是基于python2.7&lt;/li>
&lt;/ul>
&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300"
 data-srcset="https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300, https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300 1.5x, https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>搭建开发环境</title><link>https://itest2025.pages.dev/tutorials/27-002-%E6%90%AD%E5%BB%BA%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</link><pubDate>Sun, 17 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-002-%E6%90%AD%E5%BB%BA%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</guid><description>&lt;h3 id="开发环境介绍">开发环境介绍&lt;/h3>
&lt;p>我们使用python来实现最简单的爬虫。&lt;/p>
&lt;ul>
&lt;li>使用python的&lt;a href="http://docs.python-requests.org/en/master/" target="_blank" rel="noopener noreffer ">requests&lt;/a>库来发起http请求并获取目标站点的html代码。&lt;/li>
&lt;li>使用python的&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/" target="_blank" rel="noopener noreffer ">BeautifulSoup&lt;/a>库来解析html，从html中提取感兴趣的内容。&lt;/li>
&lt;/ul>
&lt;h3 id="requests教程">Requests教程&lt;/h3>
&lt;p>大家可以在&lt;a href="https://itest2025.pages.dev/requests" rel="">测试教程网requests教程&lt;/a>中找到requests库的一些典型用法。&lt;/p>
&lt;h3 id="环境搭建">环境搭建&lt;/h3>
&lt;ul>
&lt;li>安装python3，可以参考&lt;a href="https://itest2025.pages.dev/selenium_python/install-selenium/" rel="">这里&lt;/a>&lt;/li>
&lt;li>安装requests，可以参考&lt;a href="https://itest2025.pages.dev/requests/install/" rel="">这里&lt;/a>&lt;/li>
&lt;li>安装BeautifulSoup，可以参考&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup" target="_blank" rel="noopener noreffer ">这里&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="作者使用软件版本">作者使用软件版本&lt;/h3>
&lt;p>我的电脑上环境是这样&lt;/p>
&lt;ul>
&lt;li>python: 3.5.2&lt;/li>
&lt;li>requests: 2.13.0&lt;/li>
&lt;li>beautifulsoup4: 4.6.0&lt;/li>
&lt;/ul>
&lt;p>不需要与我的版本保持完全一致，只需要大于等于我使用的版本就可以了&lt;/p>
&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=300"
 data-srcset="https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=300, https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=300 1.5x, https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>最简单的web爬虫:获取所有课程信息</title><link>https://itest2025.pages.dev/tutorials/27-003-%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84web%E7%88%AC%E8%99%AB%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E8%AF%BE%E7%A8%8B%E4%BF%A1%E6%81%AF/</link><pubDate>Sat, 16 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-003-%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84web%E7%88%AC%E8%99%AB%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E8%AF%BE%E7%A8%8B%E4%BF%A1%E6%81%AF/</guid><description>&lt;h3 id="获取所有课程信息">获取所有课程信息&lt;/h3>
&lt;p>我们现在来实现第一个超级简单的网络爬虫 用来抓取&lt;a href="http://www.itest.info/courses" target="_blank" rel="noopener noreffer ">重定向科技目前开设的所有测试课程&lt;/a>，并打印出来，步骤大概是这样子&lt;/p>
&lt;ul>
&lt;li>先访问&lt;a href="http://www.itest.info/courses" target="_blank" rel="noopener noreffer ">所有课程页面&lt;/a>，把html代码拿到，实际上就是拿到一个很长的文本，文本内容就是网页的html代码&lt;/li>
&lt;li>分析html代码，找到我们需要获取信息的html特征&lt;/li>
&lt;li>解析html代码，根据html特征，从里面抠出来课程的名称&lt;/li>
&lt;li>打印出所有课程的名称&lt;/li>
&lt;/ul>
&lt;h3 id="分析html代码">分析html代码&lt;/h3>
&lt;p>我们在编写爬虫的时候往往会花很多时间在分析html代码上，毕竟重要的信息都包含在html代码中，我们需要找到合适的特征，通过固定的套路去解析html，获取特定内容。&lt;/p>
&lt;p>课程名称部分的html代码如下所示&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">div&lt;/span> &lt;span class="na">class&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;col-md-3 col-sm-6&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">div&lt;/span> &lt;span class="na">class&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;servive-block-in servive-block-colored servive-block-grey&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">h4&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>性能测试从入门到精通班&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">h4&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;&lt;/span>&lt;span class="nt">div&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;&lt;/span>&lt;span class="nt">i&lt;/span> &lt;span class="na">class&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;icon-rocket&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">i&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">div&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>2017年09月23日开课，为期3个月&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">div&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可以看到，课程名称的html标签是&lt;code>h4&lt;/code>，通过搜索整个页面，我们发现页面上只有4个h4，也就是说，只要获取到页面上所有的h4，我们就能把课程名称给解析出来。&lt;/p>
&lt;p>分析html一般有下面一些套路&lt;/p>
&lt;ul>
&lt;li>缩小范围: 只解析特定区域的html，比如只遍历&lt;code>&amp;lt;nav&amp;gt;&amp;lt;/nav&amp;gt;&lt;/code>标签中的子元素&lt;/li>
&lt;li>组合属性: 有一些节点的属性是相同的，但我们经常只需要获取其中一些节点的内容，这时候可以通过组合该节点属性和其父节点属性的方式指定特定的节点&lt;/li>
&lt;li>先遍历后过滤：还是上面一种情况，我们也可以先遍历所有的目标节点，再从目标节点中过滤出我们感兴趣的内容&lt;/li>
&lt;/ul>
&lt;h3 id="解析html代码">解析html代码&lt;/h3>
&lt;p>大家可以先去了解一下html的基础知识，比较有用的是&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://www.w3school.com.cn/html/html_elements.asp" target="_blank" rel="noopener noreffer ">html元素&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.w3school.com.cn/html/html_attributes.asp" target="_blank" rel="noopener noreffer ">html属性&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Beautiful Soup库可以帮我们解析html代码，所谓的解析，无非是做下面的一些事情&lt;/p>
&lt;ul>
&lt;li>从html文档中找到一些元素&lt;/li>
&lt;li>获取某个元素或者一些元素的属性&lt;/li>
&lt;li>获取某个元素或者一些元素的文本&lt;/li>
&lt;/ul>
&lt;p>在这个例子里，我们就是要找到所有&lt;code>h4&lt;/code>元素，并获取所有&lt;code>h4&lt;/code>元素的文本。&lt;/p>
&lt;h3 id="代码">代码&lt;/h3>
&lt;p>新建名为&lt;code>get_courses.py&lt;/code>的文件，输入下面的内容&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">bs4&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;http://www.itest.info/courses&amp;#39;&lt;/span> &lt;span class="c1"># 定义被抓取页面的url&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 获取被抓取页面的html代码，并使用html.parser来实例化BeautifulSoup，属于固定套路&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">soup&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;html.parser&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 遍历页面上所有的h4&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">course&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">soup&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_all&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;h4&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 打印出h4的text属性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">course&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="运行">运行&lt;/h3>
&lt;p>在命令行中输入&lt;/p>
&lt;pre tabindex="0">&lt;code>python get_courses.py
&lt;/code>&lt;/pre>&lt;h3 id="预期结果">预期结果&lt;/h3>
&lt;p>如果一切正常，那么应该可以看到下面的结果&lt;/p>
&lt;pre tabindex="0">&lt;code>性能测试从入门到精通班
接口自动化测试开发--Python班
Selenium自动化测试--Java班
Selenium自动化测试--Python班
&lt;/code>&lt;/pre>&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1508923567004-3a6b8004f3d7?w=300"
 data-srcset="https://images.unsplash.com/photo-1508923567004-3a6b8004f3d7?w=300, https://images.unsplash.com/photo-1508923567004-3a6b8004f3d7?w=300 1.5x, https://images.unsplash.com/photo-1508923567004-3a6b8004f3d7?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1508923567004-3a6b8004f3d7?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>层级遍历:获取所有的热门主题</title><link>https://itest2025.pages.dev/tutorials/27-004-%E5%B1%82%E7%BA%A7%E9%81%8D%E5%8E%86%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E7%9A%84%E7%83%AD%E9%97%A8%E4%B8%BB%E9%A2%98/</link><pubDate>Fri, 15 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-004-%E5%B1%82%E7%BA%A7%E9%81%8D%E5%8E%86%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E7%9A%84%E7%83%AD%E9%97%A8%E4%B8%BB%E9%A2%98/</guid><description>&lt;h3 id="稍微复杂一点的例子">稍微复杂一点的例子&lt;/h3>
&lt;p>在&lt;a href="https://www.v2ex.com/" target="_blank" rel="noopener noreffer ">v2ex&lt;/a>主页的右侧一般有个最热主题区域，里面列出了当日的热门讨论话题。这一节里我们就尝试使用爬虫技术获取这些热门主题文本和链接。&lt;/p>
&lt;p>&lt;strong>注意：v2ex本身提供了接口去获取这些热门主题的详细信息，本节内容只是举例，并不是最佳实践&lt;/strong>&lt;/p>
&lt;p>具体步骤&lt;/p>
&lt;ul>
&lt;li>访问v2ex主页，获取html文本&lt;/li>
&lt;li>分析html文本，找出待获取内容的特征&lt;/li>
&lt;li>解析html代码，根据特征拿出目标内容&lt;/li>
&lt;li>打印这些内容&lt;/li>
&lt;/ul>
&lt;h3 id="分析html代码">分析html代码&lt;/h3>
&lt;p>热门内容部分的html代码如下所示&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">span&lt;/span> &lt;span class="na">class&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;item_hot_topic_title&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">a&lt;/span> &lt;span class="na">href&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/t/415664&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>冬天了，身上静电咋处理？&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">a&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">span&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可以看出我们要找到的是所有class=item_hot_topic_title的span下面的a元素&lt;/p>
&lt;h3 id="代码">代码&lt;/h3>
&lt;p>新建名为&lt;code>v2ex_hosts.py&lt;/code>的文件，输入下面的内容&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">bs4&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://www.v2ex.com/&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">soup&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;html.parser&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">span&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">soup&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_all&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;span&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">class_&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;item_hot_topic_title&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">span&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">span&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="s1">&amp;#39;href&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="运行">运行&lt;/h3>
&lt;p>在命令行中输入&lt;/p>
&lt;pre tabindex="0">&lt;code>python v2ex_hosts.py
&lt;/code>&lt;/pre>&lt;h3 id="预期结果">预期结果&lt;/h3>
&lt;p>如果一切正常，那么应该可以看到&lt;strong>类似&lt;/strong>下面的结果，由于每天的热门主题不一样，所以内容是会变化的&lt;/p>
&lt;pre tabindex="0">&lt;code>小米感恩节不感恩 /t/415623
冬天了，身上静电咋处理？ /t/415664
违反一下政治正确，骂一下 Google /t/415600
做了将近 6 年程序员，没能成为大牛，考虑再三，决定改行，大家说，做点什么好呢？ /t/415701
结果还是被雷猴王给套路了 /t/415843
一直很好奇 Mac+安卓的组合是基于什么优势考虑的呢？ /t/415645
听说比特币要分叉了？ /t/415858
看到大学同学朋友圈发的北大成人通知书，心里不是滋味。 /t/415821
当码农 8 年了，要不要去读个研 /t/415854
新进一家公司遭遇的待遇~~ /t/415863
&lt;/code>&lt;/pre>&lt;h3 id="我们可以学到什么">我们可以学到什么&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>&lt;code>for span in soup.find_all('span', class_='item_hot_topic_title')&lt;/code>: 遍历所有的class=item_hot_topic_title的span。注意是&lt;code>class_&lt;/code>，不是&lt;code>class&lt;/code>，因为class是python的关键字，所以后面要加个尾巴，防止冲突&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>span.find('a').text&lt;/code>：层级遍历，先找到span，再从span下找到a，这是常用套路&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>span.find('a')['href']&lt;/code>：获取href属性，在bs4里，我们可以通过&lt;code>[attribute_name]&lt;/code>的方式来获取元素的属性&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="阅读内容">阅读内容&lt;/h3>
&lt;p>BeautifulSoup&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all" target="_blank" rel="noopener noreffer ">find_all&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find" target="_blank" rel="noopener noreffer ">find&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#css-selectors" target="_blank" rel="noopener noreffer ">css_selector&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#attributes" target="_blank" rel="noopener noreffer ">attributes&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>原始封面&lt;/p></description></item><item><title>图片爬虫</title><link>https://itest2025.pages.dev/tutorials/27-005-%E5%9B%BE%E7%89%87%E7%88%AC%E8%99%AB/</link><pubDate>Thu, 14 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-005-%E5%9B%BE%E7%89%87%E7%88%AC%E8%99%AB/</guid><description>&lt;h3 id="图片爬虫">图片爬虫&lt;/h3>
&lt;p>之前的例子里我们开发的都是文本爬虫，有时候我们需要去下载其他网站的图片并保存下来，这时候就需要用图片爬虫。&lt;/p>
&lt;p>图片爬虫的套路其实跟文本爬虫差不多，最大的区别就是图片爬虫会去下载需要的文件，而文本爬虫可能会做其他的一些持久化的工作。&lt;/p>
&lt;p>在这一节里，我们将实现下载&lt;a href="http://jandan.net/drawings" target="_blank" rel="noopener noreffer ">煎蛋画廊&lt;/a>第一页所有图片的功能。&lt;/p>
&lt;p>具体步骤&lt;/p>
&lt;ul>
&lt;li>访问煎蛋画廊主页，获取html文本&lt;/li>
&lt;li>分析html文本，找出所有图片的html特征&lt;/li>
&lt;li>解析html代码，拿到所有图片的src&lt;/li>
&lt;li>通过src去下载图片&lt;/li>
&lt;/ul>
&lt;h3 id="分析html代码">分析html代码&lt;/h3>
&lt;p>图片的html标签是img，所以我们只需要拿到页面上所有的img标签的src就好了。&lt;/p>
&lt;h3 id="下载文件">下载文件&lt;/h3>
&lt;p>通过下面的代码，我们可以使用requests库来下载文件。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">download_file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Downding &lt;/span>&lt;span class="si">%s&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span> &lt;span class="o">%&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">local_filename&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">url&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/&amp;#39;&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">stream&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">local_filename&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;wb&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">chunk&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">iter_content&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">chunk&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">flush&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">local_filename&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>download_file方法只需要传入具体文件的地址就可以完成下载文件的功能了。&lt;/p>
&lt;h3 id="user-agent">user agent&lt;/h3>
&lt;p>由于煎蛋做了非常简单的反爬虫处理，该站点会拒绝所有看起来像是爬虫的请求，大概的逻辑可能是如果后台发现请求的user agent异常，就返回403错误。&lt;/p>
&lt;p>这里是&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent" target="_blank" rel="noopener noreffer ">User-Agent&lt;/a>的基础知识，大家可以自行学习。&lt;/p>
&lt;p>我们可以通过requests非常方便的修改请求的user agent，从而让被访问站点的后台没有办法识别出这次请求是否异常，达到绕过反爬机制的目的。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">headers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;user-agent&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">headers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">headers&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>上面代码的核心思想就是通过修改http headers中user agent，达到将请求伪装成是来自普通chrome浏览器访问的目的。&lt;/p>
&lt;h3 id="代码">代码&lt;/h3>
&lt;p>新建名为&lt;code>get_images.py&lt;/code>的文件，输入下面的内容&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">bs4&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">headers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;user-agent&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">download_file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Downding &lt;/span>&lt;span class="si">%s&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span> &lt;span class="o">%&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">local_filename&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">url&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/&amp;#39;&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">stream&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">headers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">headers&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">local_filename&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;wb&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">chunk&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">r&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">iter_content&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">chunk&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">flush&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">local_filename&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;http://jandan.net/drawings&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">soup&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">headers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">headers&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;html.parser&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">valid_img&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">src&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">src&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">endswith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;jpg&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="s1">&amp;#39;img.jandan.net&amp;#39;&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">img&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">soup&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_all&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;img&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">valid_img&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">img&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;src&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">src&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">startswith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;http&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;http:&amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">download_file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">src&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="运行">运行&lt;/h3>
&lt;p>在命令行中输入&lt;/p></description></item><item><title>爬虫对抗</title><link>https://itest2025.pages.dev/tutorials/27-006-%E7%88%AC%E8%99%AB%E5%AF%B9%E6%8A%97/</link><pubDate>Wed, 13 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-006-%E7%88%AC%E8%99%AB%E5%AF%B9%E6%8A%97/</guid><description>&lt;h3 id="why">why&lt;/h3>
&lt;p>知己知彼，百战不殆。&lt;/p>
&lt;p>爬虫往往会爬取其他服务的一些核心资源，这些资源是服务提供商重点保护的资产，所以很多网站都会启用一些反爬虫策略。&lt;/p>
&lt;p>这里我们简单分析一下反爬虫的常用手段。&lt;/p>
&lt;h3 id="监控后台日志和流量模式-如果发现异常活动则限制访问">监控后台日志和流量模式; 如果发现异常活动，则限制访问&lt;/h3>
&lt;p>通过日志是可以看出一些异常访问的，比如例如来自同一个IP地址的许多类似的请求操作。我们可以通过一些措施来限制这些访问，从而达到保护己方资源的效果，具体措施如下&lt;/p>
&lt;ul>
&lt;li>访问速率限制&lt;/li>
&lt;li>检测异常活动&lt;/li>
&lt;li>不要只是通过IP地址监控和限制访问速率 —— 也可以使用其他指标，比如表单提交的速度，或者是user-agent&lt;/li>
&lt;li>使用验证码替代临时阻止访问的方案&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>反爬建议:可以使用ip池，降低访问频率或浏览器自动化工具爬虫来进行对抗&lt;/strong>&lt;/p>
&lt;h3 id="要求注册和登录">要求注册和登录&lt;/h3>
&lt;p>如果你要求客户端创建帐户和登录，那么你可以准确的跟踪用户和爬虫的操作，另外也可以适当增加爬虫实现的难度。不过需不需要注册和登录最终还要看产品的需求，以产品需求为准。&lt;/p>
&lt;p>为了避免自动化创建许多帐户的脚本，你应该做以下这些事情:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>注册时需要一个电子邮件地址，并且用户必须打开通过你所发送的链接来验证该电子邮件地址才能激活该帐户。每个电子邮件地址只允许一个帐户。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>需要在注册/帐户创建期间显示验证码，以防止自动化脚本创建帐户&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>反爬建议:爬虫可以模拟登录，另外降低访问频率，以免暴露真实意图&lt;/strong>&lt;/p>
&lt;h3 id="阻止来自云托管主机和爬虫服务的ip地址的访问">阻止来自云托管主机和爬虫服务的IP地址的访问&lt;/h3>
&lt;p>有时，爬虫会从网络托管服务（如Amazon Web Services或Google App Engine）或VPSes运行。限制（或显示验证码）来源于此类云主机服务使用的IP地址请求访问你的网站。你还可以阻止从爬虫服务使用的IP地址的访问。&lt;/p>
&lt;p>同样，你还可以限制代理或VPN提供商使用的IP地址的访问，因为爬虫可能会使用此类代理服务器来避免单个IP发出许多请求。&lt;/p>
&lt;p>&lt;strong>反爬建议:使用代理和ip池&lt;/strong>&lt;/p>
&lt;h3 id="如果你要采取阻止访问的做法请将你的错误消息进行调整">如果你要采取阻止访问的做法，请将你的错误消息进行调整&lt;/h3>
&lt;p>如果你采取了阻止/限制访问的手段，那么你应该确保不要告诉爬虫导致阻塞的实际原因，从而给爬虫制作者如何修复爬虫的线索。所以用文本显示错误页面可能是一个坏主意：&lt;/p>
&lt;ul>
&lt;li>你的IP地址请求过于频繁，请稍后再试。&lt;/li>
&lt;li>错误，User Agent不存在，非法访问！&lt;/li>
&lt;/ul>
&lt;p>相反，显示一个友好的错误消息，不要告诉爬虫是什么原因造成不能正常访问的。&lt;/p>
&lt;p>抱歉，网站出了一些问题。如果问题仍然存在，你可以联系helpdesk@example.com。&lt;/p>
&lt;p>这也是真正对用户友好的一种显示内容。你还应该考虑在后续的请求中不要直接显示验证码，以防真实用户看到这个错误消息，导致你阻止了合法用户的访问行为。&lt;/p>
&lt;p>&lt;strong>反爬建议:使用浏览器自动化工具，伪装成真实的用户&lt;/strong>&lt;/p>
&lt;h3 id="如果你的网站被爬虫访问请使用验证码">如果你的网站被爬虫访问，请使用验证码&lt;/h3>
&lt;p>验证码是双刃剑，可以非常有效的组织爬虫，但也会对真正的用户产生负面影响。&lt;/p>
&lt;p>如果需要使用验证码，那么请&lt;/p>
&lt;ul>
&lt;li>
&lt;p>不要自己实现验证码，应该使用像Google的reCaptcha这样的东西：这比自己实现一个验证码要容易得多，它比一些模糊和扭曲的文本解决方案对用户来说更友好，而且比起自己实现验证码，它能更好的解决问题&lt;/p>
&lt;/li>
&lt;li>
&lt;p>不要在HTML标记中包含验证码的解决方案：实际上我已经看到一个网站在页面中嵌入了验证码的解决方案（虽然隐藏的很好）。但是不要这样做。还是推荐使用像reCaptcha这样的服务，如果你正确使用它，就不会出现问题。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>验证码是可以批量验证的：在网上有一些低报酬的人工打码服务可以批量解决验证码的验证服务。所以，我在这里还是推荐使用reCaptcha，因为它具有很好的自我保护作用。这种服务不太可能被用于人工打码，除非你的数据真的很有价值。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>反爬建议:使用人肉打码服务&lt;/strong>&lt;/p>
&lt;h3 id="将你的文本内容转成图片">将你的文本内容转成图片&lt;/h3>
&lt;p>你可以在服务器端将文本转换成图像然后在客户端显示，这种方法可以阻碍简单的爬虫提取文本。&lt;/p>
&lt;p>记得当年起点的付费阅读的内容就全部是图片形式的。&lt;/p>
&lt;p>然而，这对于屏幕阅读器，搜索引擎，性能以及其他的一些事情都是不利的。在某些方面（比如无障碍操作，例如美国残疾人法案）也可能是非法的，并且也很容易被一些OCR技术绕过，所以最好还是不要这样做。&lt;/p>
&lt;p>&lt;strong>反爬建议:使用OCR图片识别技术&lt;/strong>&lt;/p>
&lt;h3 id="不要公开你的完整数据集">不要公开你的完整数据集&lt;/h3>
&lt;p>如果可行的话，请不要为脚本或爬虫机器人提供所有数据集的方法。例如：你有一个新闻网站，有很多单独的文章。你可以通过现场搜索来搜索这些文章，并且如果你没有列出任何网站上的所有文章及其URL，那么这些文章将只能通过使用搜索来访问特征。这意味着一个想要从你的网站上获得所有文章的脚本将不得不搜索可能出现在你的文章中的所有可能的短语，才能找到文章的全部内容，这对于爬虫来说是很耗时的，而且效率低的可怕，所以爬虫一般都会放弃爬取数据。&lt;/p>
&lt;p>如果是以下这些情况，那么这种方法将变得无效：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>爬虫机器人或脚本并不想或需要完整的数据集。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>你的文章的URL是一个看起来像 example.com/article.php?articleId=12345这种（和类似的东西）的格式，这将允许爬虫可以简单地迭代所有articleId的文章，并请求所有的文章内容。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>还有其他方式可以最终找到所有的文章，比如通过编写一个脚本来跟踪其他文章的内容中的链接。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>搜索“&amp;amp;”或“”的东西可以显示几乎所有的东西，这是一些需要注意的事情。（你只能返回前10或20个结果来避免这种情况）。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>你需要搜索引擎来查找你的内容。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>反爬建议:遍历数字型id基本可以拿到所有内容&lt;/strong>&lt;/p>
&lt;h3 id="参考资料">参考资料&lt;/h3>
&lt;p>文本大部分参考了&lt;a href="http://www.4hou.com/technology/8482.html" target="_blank" rel="noopener noreffer ">Web网页爬虫对抗指南 Part.1&lt;/a>这篇文章，在这里附上原始链接，并对原作者和译者表示衷心的感谢。&lt;/p>
&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1504893524553-b855bce32c67?w=300"
 data-srcset="https://images.unsplash.com/photo-1504893524553-b855bce32c67?w=300, https://images.unsplash.com/photo-1504893524553-b855bce32c67?w=300 1.5x, https://images.unsplash.com/photo-1504893524553-b855bce32c67?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1504893524553-b855bce32c67?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>另一个例子: 知乎最热问题</title><link>https://itest2025.pages.dev/tutorials/27-007-%E5%8F%A6%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90-%E7%9F%A5%E4%B9%8E%E6%9C%80%E7%83%AD%E9%97%AE%E9%A2%98/</link><pubDate>Wed, 13 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-007-%E5%8F%A6%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90-%E7%9F%A5%E4%B9%8E%E6%9C%80%E7%83%AD%E9%97%AE%E9%A2%98/</guid><description>&lt;h3 id="需求">需求&lt;/h3>
&lt;p>在这一节里，我们将实现获取&lt;a href="https://www.zhihu.com/explore" target="_blank" rel="noopener noreffer ">知乎每日及每月最热问题&lt;/a>的功能。&lt;/p>
&lt;p>具体步骤&lt;/p>
&lt;ul>
&lt;li>访问知乎的发现的主页，获取html文本&lt;/li>
&lt;li>分析html文本，找出今日最热和本月最热的html特征&lt;/li>
&lt;li>解析html代码，拿到所有满足条件的链接&lt;/li>
&lt;li>拿到链接的文本，并打印&lt;/li>
&lt;/ul>
&lt;h3 id="分析html代码">分析html代码&lt;/h3>
&lt;pre tabindex="0">&lt;code>&amp;lt;a class=&amp;#34;question_link&amp;#34; href=&amp;#34;/question/264469853/answer/281600357&amp;#34; target=&amp;#34;_blank&amp;#34; data-id=&amp;#34;20218891&amp;#34; data-za-element-name=&amp;#34;Title&amp;#34;&amp;gt;
如何看待张召忠（局座）于12月22日在b站的《荒野行动》直播？
&amp;lt;/a&amp;gt;
&lt;/code>&lt;/pre>&lt;p>稍微分析一下可以看出，我们只需要拿到所有class=&amp;ldquo;question_link&amp;quot;的a标签就可以了。&lt;/p>
&lt;h3 id="代码">代码&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># zhihu.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">bs4&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://www.zhihu.com/explore&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">headers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;user-agent&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">soup&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BeautifulSoup&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">headers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">headers&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;html.parser&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">link&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">soup&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_all&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">class_&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;question_link&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">link&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="运行">运行&lt;/h3>
&lt;p>命令行中运行&lt;/p>
&lt;pre tabindex="0">&lt;code>python zhihu.py
&lt;/code>&lt;/pre>&lt;h3 id="预期结果">预期结果&lt;/h3>
&lt;p>由于内容是动态的，所以结果应该跟我的结果不尽相同&lt;/p>
&lt;pre tabindex="0">&lt;code>如何看待美税改通过后各大公司的发福利提最低工资追加投资等行为？


全球变暖是必然吗？


主播进行游戏直播并从中获得打赏盈利涉及侵犯版权吗？


如何看待张召忠（局座）于12月22日在b站的《荒野行动》直播？


影史上有哪些经典的即兴表演镜头？


十年坚持做一件事，是种怎样的体验？


2018 年应届硕士毕业生如何拿到知名互联网公司深度学习 offer？


迄今为止你见过的最惊艳的建筑是？


有哪些令人心碎的小故事？


有哪些轻松幽默而又不低俗的段子或图片？


为什么人会失去婴儿时期的记忆？最早记忆是几岁呢？


你最喜欢的故事是什么？


做一个可爱的女孩子是一种什么体验？
&lt;/code>&lt;/pre>&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1498550744921-75f79806b8a7?w=300"
 data-srcset="https://images.unsplash.com/photo-1498550744921-75f79806b8a7?w=300, https://images.unsplash.com/photo-1498550744921-75f79806b8a7?w=300 1.5x, https://images.unsplash.com/photo-1498550744921-75f79806b8a7?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1498550744921-75f79806b8a7?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>推荐资源</title><link>https://itest2025.pages.dev/tutorials/27-008-%E6%8E%A8%E8%8D%90%E8%B5%84%E6%BA%90/</link><pubDate>Mon, 11 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-008-%E6%8E%A8%E8%8D%90%E8%B5%84%E6%BA%90/</guid><description>&lt;p>为了大家能够更好的学习爬虫，扩大视野，这里给大家推荐一些其他的资源&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://blog.thankbabe.com/2017/09/25/spider/" target="_blank" rel="noopener noreffer ">大话爬虫的基本套路&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://blog.fundebug.com/2017/11/01/guide-to-automating-scraping-the-web-with-js/" target="_blank" rel="noopener noreffer ">Puppeteer之爬虫入门&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.zhihu.com/question/27621722/answer/51254997" target="_blank" rel="noopener noreffer ">利用爬虫技术能做到哪些很酷很有趣很有用的事情？&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.4hou.com/technology/8482.html" target="_blank" rel="noopener noreffer ">Web网页爬虫对抗指南 Part.1&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zhuanlan.zhihu.com/p/21479334" target="_blank" rel="noopener noreffer ">如何学习python爬虫&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/facert/awesome-spider" target="_blank" rel="noopener noreffer ">各种爬虫实例, 强烈推荐&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=300"
 data-srcset="https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=300, https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=300 1.5x, https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=300"
 title="课程图片" />&lt;/p></description></item><item><title>selenium爬虫</title><link>https://itest2025.pages.dev/tutorials/27-009-selenium%E7%88%AC%E8%99%AB/</link><pubDate>Mon, 11 Dec 2017 02:52:34 +0800</pubDate><guid>https://itest2025.pages.dev/tutorials/27-009-selenium%E7%88%AC%E8%99%AB/</guid><description>&lt;h3 id="why">why&lt;/h3>
&lt;p>从上一节的反爬虫建议来看，降低访问频率和将爬虫伪装成真实的用户访问可以对抗大部分的反爬虫策略。&lt;/p>
&lt;p>因为selenium是完全操作真实的浏览器，所以发爬虫策略比较难察觉异常，对于一些反爬虫策略非常严酷的网站，用selenium爬虫有时候会起到意想不到的效果。&lt;/p>
&lt;p>但是selenium爬虫也有一些局限性，比如效率低下等。&lt;/p>
&lt;h3 id="需求">需求&lt;/h3>
&lt;p>我们使用selenium爬虫来获取&lt;a href="https://www.zhihu.com/explore" target="_blank" rel="noopener noreffer ">知乎今日最热&lt;/a>的问题列表。跟之前的知乎爬虫差不多。&lt;/p>
&lt;h3 id="搭建开发环境">搭建开发环境&lt;/h3>
&lt;p>我们需要使用selenium和chrome driver，具体的安装方式请参考&lt;a href="http://www.testclass.net/selenium_python/install-selenium/" target="_blank" rel="noopener noreffer ">这里&lt;/a>&lt;/p>
&lt;h3 id="代码">代码&lt;/h3>
&lt;p>在这里我们就不分析html代码了，打开页面用开发者工具可以看到，今日最热的内容实际上就是找到&lt;code>data-type=&amp;quot;daily&amp;quot;&lt;/code>的div下，所有的&lt;code>class=question_link&lt;/code>的a元素。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># se_zhihu.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">selenium&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">webdriver&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://www.zhihu.com/explore&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">webdriver&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Chrome&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dr&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">daily_div&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dr&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_element_by_css_selector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;div[data-type=&amp;#34;daily&amp;#34;]&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">link&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">daily_div&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">find_elements_by_css_selector&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;.question_link&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">link&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dr&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">quit&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="运行">运行&lt;/h3>
&lt;p>命令行中直接运行&lt;/p>
&lt;pre tabindex="0">&lt;code>python se_zhihu.py
&lt;/code>&lt;/pre>&lt;h3 id="结果">结果&lt;/h3>
&lt;p>由于动态内容的关系，结果可能不尽相同。&lt;/p>
&lt;pre tabindex="0">&lt;code>如何看待美税改通过后各大公司的发福利提最低工资追加投资等行为？


全球变暖是必然吗？


主播进行游戏直播并从中获得打赏盈利涉及侵犯版权吗？


如何看待张召忠（局座）于12月22日在b站的《荒野行动》直播？


影史上有哪些经典的即兴表演镜头？
&lt;/code>&lt;/pre>&lt;h3 id="我们可以学到什么">我们可以学到什么&lt;/h3>
&lt;ul>
&lt;li>selenium操作浏览器可以实现一些爬虫行为&lt;/li>
&lt;li>selenium爬虫的效率很低&lt;/li>
&lt;li>可以使用headless(无界面的浏览器)来提升selenium爬虫的效率&lt;/li>
&lt;li>如果你对selenium的api不熟悉，可以直接使用Puppeteer来做爬虫，详情请看&lt;a href="https://blog.fundebug.com/2017/11/01/guide-to-automating-scraping-the-web-with-js/" target="_blank" rel="noopener noreffer ">这篇文章&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>原始封面&lt;/p>
&lt;p>&lt;img
 class="lazyload"
 src="https://itest2025.pages.dev/svg/loading.min.svg"
 data-src="https://images.unsplash.com/photo-1464983953574-0892a716854b?w=300"
 data-srcset="https://images.unsplash.com/photo-1464983953574-0892a716854b?w=300, https://images.unsplash.com/photo-1464983953574-0892a716854b?w=300 1.5x, https://images.unsplash.com/photo-1464983953574-0892a716854b?w=300 2x"
 data-sizes="auto"
 alt="https://images.unsplash.com/photo-1464983953574-0892a716854b?w=300"
 title="课程图片" />&lt;/p></description></item></channel></rss>