本文与大家分享一个网络爬虫的使用案例分析。小编觉得还是比较实用的,所以分享给大家,供大家参考。下面就跟随小编一起来看看吧。
1. 为什么要使用网络爬虫?
因为语言非常简洁,易于使用和学习,所以写作就像用英语写作一样。另外,使用起来也非常方便。它不需要 IDE,而仅使用文本。可以开发大多数中小型应用;另外,爬虫框架非常强大。其框架可以抓取网络数据并提取结构数据。常用于数据挖掘、历史数据存储、信息处理等程序中;网络支持库和html解析器非常强大。借助网络支持库,只需编写较少的代码就可以下载网页,并通过网页解析库可以解析网页中的每个标签,并与正则表达式结合起来。
抓取网页内容非常方便。因此,它在网络爬行方面具有很大的优势。
2、判断网站数据是否支持抓取
几乎每个网站都有一个名为 .txt 的文档。当然,有些网站不设置.txt。如果网站没有设置.txt,则可以通过网络爬虫获取无密码加密的数据,即可以爬取该网站的所有页面数据。当然,如果网站有.txt文档,就要判断是否存在禁止访问者获取的数据。
以淘宝为例,在浏览器中访问,如图。
上图中淘宝上.txt文件的内容
淘宝允许某些爬虫访问其部分路径,但对于不允许的用户,则禁止所有爬行。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>User-Agent:*
Disallow:/
12
</span></pre></p>
这段代码的含义是,除了前面指定的爬虫之外,其他爬虫不允许爬取任何数据。
3. 图书馆抓取网站数据
1.如何安装库
1.首先安装库
2.打开并单击“文件”菜单
3. 选择“新建...”命令
4. 选择“ ”(项目编译器)命令
5、确认当前选择的编译器,点击右上角的加号。
6、在搜索框中输入:(注意,一定要输入完整,否则很容易出错),然后点击左下角的“ ”(安装库)按钮。
安装完成后会显示“''”(库请求已成功安装)。如果安装不成功,会出现提示信息。
4.爬虫的基本原理
网页请求的过程分为两个环节:
(请求):每个显示在用户面前的网页都必须经过这一步,即向服务器发送访问请求。
(响应):服务器收到用户的请求后,会验证请求的有效性,然后将响应内容发送给用户(客户端)。客户端接收服务器响应的内容并显示内容,这就是我们所熟悉的。网页请求
请求网页有两种方式:
GET:最常用的方法,一般用于获取或查询资源信息。也是大多数网站采用的方法,响应速度快。
POST:与GET方法相比,它具有以表单形式上传参数的功能,所以除了查询信息外,还可以修改信息。
因此,在编写爬虫之前,首先要确定将请求发送给谁以及如何发送。
5.使用GET方法抓取数据
复制首页任意第一条新闻的标题,在源页面按【Ctrl+F】调出搜索框,将标题粘贴到搜索框中,然后按【Enter】键。
标题可以在源码中搜索到,请求对象是,请求方法是GET(源码中所有数据请求方法都是GET),如图9所示。
确定请求对象和方法后,在中输入以下代码:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import requests #导入requests包
url = 'http://www.cntour.cn/'
strhtml = requests.get(url) #Get方式获取网页数据
print(strhtml.text)
1234
</span></pre></p>
用于加载库的语句是+库的名称。上述过程中,加载库的语句为: 。
使用GET方法获取数据,需要调用库中的get方法。要使用它,请在其后面输入英文句点,如下所示:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>requests.get
1
</span></pre></p>
将获取到的数据存入变量中,代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>strhtml = request.get(url)
1
</span></pre></p>
这次是一个URL对象,它代表了整个网页,但此时只需要网页中的源代码。以下语句代表网页源代码:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false">strhtml.text
1</pre></p>
6.使用POST方法抓取数据
首先输入有道翻译网址:进入有道翻译页面。
按快捷键F12进入开发者模式,点击。此时内容为空,如图:
在有道翻译中输入“我爱中国”,点击“翻译”按钮
在开发者模式下,点击“”按钮,然后点击“XHR”按钮即可查找翻译数据
点击发现请求数据的方法是POST。
找到数据在哪里以及如何请求数据后,开始编写爬虫程序。
首先,将 URL 复制进去并将其分配给 url。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
1
</span></pre></p>
POST请求获取数据的方式与GET不同。 POST 请求数据必须构造请求头。
Form Data中请求参数如图
复制它并建立一个新字典:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>From_data={'i':'我愛中國','from':'zh-CHS','to':'en','smartresult':'dict','client':'fanyideskweb','salt':'15477056211258','sign':'b3589f32c38bc9e3876a570b8a992604','ts':'1547705621125','bv':'b33a2f3f9d09bde064c9275bcb33d94e','doctype':'json','version':'2.1','keyfrom':'fanyi.web','action':'FY_BY_REALTIME','typoResult':'false'}
1
</span></pre></p>
将字符串格式数据转换为JSON格式数据,根据数据结构提取数据,并打印出翻译结果。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import json
content = json.loads(response.text)
print(content['translateResult'][0][0]['tgt'])
123
</span></pre></p>
使用.post方法抓取有道翻译结果的完整代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import requests #导入requests包
import json
def get_translate_date(word=None):
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
From_data={'i':word,'from':'zh-CHS','to':'en','smartresult':'dict','client':'fanyideskweb','salt':'15477056211258','sign':'b3589f32c38bc9e3876a570b8a992604','ts':'1547705621125','bv':'b33a2f3f9d09bde064c9275bcb33d94e','doctype':'json','version':'2.1','keyfrom':'fanyi.web','action':'FY_BY_REALTIME','typoResult':'false'}
#请求表单数据
response = requests.post(url,data=From_data)
#将Json格式字符串转字典
content = json.loads(response.text)
print(content)
#打印翻译后的数据
#print(content['translateResult'][0][0]['tgt'])
if __name__=='__main__':
get_translate_date('我爱中国')
1234567891011121314
</span></pre></p>
7. 使用Soup解析网页
网页的源代码已经可以通过库捕获。下一步是从源代码中查找并提取数据。 Soup是一个库,主要功能是从网页中爬取数据。 Soup已经移植到bs4库,这意味着导入Soup时需要先安装bs4库。
安装bs4库的方式如图:
安装bs4库后,还需要安装lxml库。如果我们不安装 lxml 库,将使用默认解析器。虽然Soup既支持标准库中的HTML解析器,也支持一些第三方解析器,但lxml库更强大、速度更快,因此作者建议安装lxml库。
安装第三方库后,输入以下代码即可开始Soup之旅:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import requests #导入requests包
from bs4 import BeautifulSoup
url='http://www.cntour.cn/'
strhtml=requests.get(url)
soup=BeautifulSoup(strhtml.text,'lxml')
data = soup.select('#main>div>div.mtop.firstMod.clearfix>div.centerBox>ul.newsList>li>a')
print(data)
1234567
</span></pre></p>
代码运行结果如图所示。
Soup库可以轻松解析网页信息。它集成在bs4库中,需要时可以从bs4库中调用。其表达式语句如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>from bs4 import BeautifulSoup
1
</span></pre></p>
首先,HTML文档将被转换为编码格式,然后Soup选择最合适的解析器来解析这个文档。这里指定lxml解析器进行解析。解析之后,复杂的HTML文档被转换成树形结构,每个节点都是一个对象。这里,解析后的文档存储在新创建的变量 soup 中。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>soup=BeautifulSoup(strhtml.text,'lxml')
1
</span></pre></p>
接下来,使用(选择器)来定位数据。定位数据时,需要使用浏览器的开发者模式。将鼠标光标置于相应的数据位置并单击右键,然后在快捷菜单中选择“检查”命令。
然后浏览器右侧会弹出开发者界面。右侧突出显示的代码(参见图 19(b))对应于左侧突出显示的数据文本(参见图 19(a))。右键单击右侧突出显示的数据,在弹出的快捷菜单中选择“复制”➔“复制”命令,即可自动复制路径。
使用以下代码将路径粘贴到文档中:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li:nth-child(1) > a
1
</span></pre></p>
由于该路径是第一个选择的路径,而且我们需要获取所有标题,所以删除li:nth-child(1)中冒号(包括冒号)后面的部分。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a
1
</span></pre></p>
用汤。引用该路径,代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false">data = soup.select('#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a')
1</pre></p>
8. 清理和组织数据
至此,一段目标HTML代码已经获得,但数据还没有提取出来。接下来,在:纯文本复制中输入以下代码
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>for item in data:
result={
'title':item.get_text(),
'link':item.get('href')
}
print(result)
123456
</span></pre></p>
代码运行结果如图:
首先,明确要提取的数据是标题和链接。标题位于 <a> 标记中。使用 () 方法提取标签的文本。该链接位于 <a> 标记的 href 属性中。要提取标签中的 href 属性,请使用 get() 方法。括号内指定要提取的属性数据,即get('href')。
从图 20 中可以看出,文章的链接中有一个数字 ID。下面使用正则表达式来提取此 ID。需要使用的正则符号如下: \d 匹配数字 + 匹配前一个字符1次或多次
re 库在调用正则表达式时使用。该库不需要安装,可以直接调用。在中输入以下代码:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import re
for item in data:
result={
"title":item.get_text(),
"link":item.get('href'),
'ID':re.findall('\d+',item.get('href'))
}
print(result)
12345678
</span></pre></p>
运行结果如图:
这里使用了re库的方法。第一个参数代表正则表达式,第二个参数代表要提取的文本。
9.爬虫攻击与防御
爬虫模拟人类浏览行为,批量抓取数据。当捕获的数据量逐渐增大时,会给访问的服务器带来很大的压力,甚至可能崩溃。换句话说,服务器不喜欢有人抓取自己的数据。然后,网站会针对这些爬虫采取一些反爬虫策略。
服务器识别爬虫的第一种方式是检查连接,识别是浏览器访问的还是代码访问的。如果是代码访问,当访问量增加时,服务器会直接屏蔽访问IP。
那么对于这种简陋的反爬虫机制我们应该采取什么措施呢?
我们以之前创建的爬虫为例。访问时我们不仅可以找到开发者环境中的URL和Form Data,还可以构造浏览器的请求头并自己封装。服务器识别浏览器访问的方式是判断是否是下面的User-Agent,如图:
因此,我们只需要构造这个请求头的参数即可。只需创建请求头信息即可,代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}
response = request.get(url,headers=headers)
12
</span></pre></p>
说到这里,很多读者会觉得修改User-Agent太简单了。确实很简单,但是正常人一秒钟看一张图片,而爬虫一秒钟可以爬很多张图片,比如一秒钟上百张图片,那么服务器的压力必然会增大。也就是说,如果你在一个IP下批量访问、下载图片,这种行为就不符合人类的正常行为,这个IP肯定会被封。
原理也很简单。就是统计每个IP的访问频率。如果频率超过阈值,将返回验证码。如果确实是用户访问,则用户将其填写并继续访问。如果是代码访问,IP会被封。
这个问题有两种解决方案。第一个是添加一个常用的延迟,即每3秒捕获一次。代码如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="brush:js;toolbar:false;"><span>import time
time.sleep(3)
12
</span></pre></p>
然而,我们编写爬虫的目的是为了批量高效地爬取数据。这里我们设置爬虫每3秒爬一次,效率太低了。其实还有一个更重要的解决办法,就是从本质上解决问题。
无论如何访问,服务器的目的都是找出哪些是通过代码访问的,然后封锁IP。解决方案:为了避免IP被封,数据采集时经常使用代理。当然,也有相应的属性。
感谢您的阅读!这里分享一下网络爬虫的使用案例分析。希望以上内容能够给大家带来一些帮助,让大家学到更多的知识。如果您觉得文章不错,可以分享出去,让更多的人看到! |