Python入门网络爬虫之精华版

优采云 发布时间: 2022-09-11 10:45

  Python入门网络爬虫之精华版

  Python学习网络爬虫主要分3个大的版块:抓取,分析,存储

  另外,比较常用的爬虫框架Scrapy,这里最后也详细介绍一下。

  首先列举一下本人总结的相关文章,这些覆盖了入门网络爬虫需要的基本概念和技巧:宁哥的小站-网络爬虫

  当我们在浏览器中输入一个url后回车,后台会发生什么?比如说你输入,你就会看到宁哥的小站首页。

  简单来说这段过程发生了以下四个步骤:

  网络爬虫要做的,简单来说,就是实现浏览器的功能。通过指定url,直接返回给用户所需要的数据,而不需要一步步人工去操纵浏览器获取。

  转载:宁哥的小站»Python入门网络爬虫之精华版

  抓取

  这一步,你要明确要得到的内容是什么?是HTML源码,还是Json格式的字符串等。

  1. 最基本的抓取

  抓取大多数情况属于get请求,即直接从对方服务器上获取数据。

  首先,Python中自带urllib及urllib2这两个模块,基本上能满足一般的页面抓取。另外,requests也是非常有用的包,与此类似的,还有httplib2等等。

  Requests:<br />    import requests<br />    response = requests.get(url)<br />    content = requests.get(url).content<br />    print "response headers:", response.headers<br />    print "content:", content<br />Urllib2:<br />    import urllib2<br />    response = urllib2.urlopen(url)<br />    content = urllib2.urlopen(url).read()<br />    print "response headers:", response.headers<br />    print "content:", content<br />Httplib2:<br />    import httplib2<br />    http = httplib2.Http()<br />    response_headers, content = http.request(url, 'GET')<br />    print "response headers:", response_headers<br />    print "content:", content<br />

  此外,对于带有查询字段的url,get请求一般会将来请求的数据附在url之后,以?分割url和传输数据,多个参数用&连接。

  data = {'data1':'XXXXX', 'data2':'XXXXX'}<br />Requests:data为dict,json<br />    import requests<br />    response = requests.get(url=url, params=data)<br />Urllib2:data为string<br />    import urllib, urllib2    <br />    data = urllib.urlencode(data)<br />    full_url = url+'?'+data<br />    response = urllib2.urlopen(full_url)<br />

  2. 对于登陆情况的处理

  2.1 使用表单登陆

  这种情况属于post请求,即先向服务器发送表单数据,服务器再将返回的cookie存入本地。

  data = {'data1':'XXXXX', 'data2':'XXXXX'}<br />Requests:data为dict,json<br />    import requests<br />    response = requests.post(url=url, data=data)<br />Urllib2:data为string<br />    import urllib, urllib2    <br />    data = urllib.urlencode(data)<br />    req = urllib2.Request(url=url, data=data)<br />    response = urllib2.urlopen(req)<br />

  2.2 使用cookie登陆

  使用cookie登陆,服务器会认为你是一个已登陆的用户,所以就会返回给你一个已登陆的内容。因此,需要验证码的情况可以使用带验证码登陆的cookie解决。

  

  import requests            <br />requests_session = requests.session() <br />response = requests_session.post(url=url_login, data=data)<br />

  若存在验证码,此时采用response = requests_session.post(url=url_login, data=data)是不行的,做法应该如下:

  response_captcha = requests_session.get(url=url_login, cookies=cookies)<br />response1 = requests.get(url_login) # 未登陆<br />response2 = requests_session.get(url_login) # 已登陆,因为之前拿到了Response Cookie!<br />response3 = requests_session.get(url_results) # 已登陆,因为之前拿到了Response Cookie!<br />

  3. 对于反爬虫机制的处理

  3.1 使用代理

  适用情况:限制IP地址情况,也可解决由于“频繁点击”而需要输入验证码登陆的情况。

  这种情况最好的办法就是维护一个代理IP池,网上有很多免费的代理IP,良莠不齐,可以通过筛选找到能用的。对于“频繁点击”的情况,我们还可以通过限制爬虫访问网站的频率来避免被网站禁掉。

  proxies = {'http':'http://XX.XX.XX.XX:XXXX'}<br />Requests:<br />    import requests<br />    response = requests.get(url=url, proxies=proxies)<br />Urllib2:<br />    import urllib2<br />    proxy_support = urllib2.ProxyHandler(proxies)<br />    opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)<br />    urllib2.install_opener(opener) # 安装opener,此后调用urlopen()时都会使用安装过的opener对象<br />    response = urllib2.urlopen(url)<br />

  3.2 时间设置

  适用情况:限制频率情况。

  Requests,Urllib2都可以使用time库的sleep()函数:

  import time<br />time.sleep(1)<br />

  3.3 伪装成浏览器,或者反“反盗链”

  有些网站会检查你是不是真的浏览器访问,还是机器自动访问的。这种情况,加上User-Agent,表明你是浏览器访问即可。有时还会检查是否带Referer信息还会检查你的Referer是否合法,一般再加上Referer。

  headers = {'User-Agent':'XXXXX'} # 伪装成浏览器访问,适用于拒绝爬虫的网站<br />headers = {'Referer':'XXXXX'}<br />headers = {'User-Agent':'XXXXX', 'Referer':'XXXXX'}<br />Requests:<br />    response = requests.get(url=url, headers=headers)<br />Urllib2:<br />    import urllib, urllib2   <br />    req = urllib2.Request(url=url, headers=headers)<br />    response = urllib2.urlopen(req)<br />

  4. 对于断线重连

  def multi_session(session, *arg):<br />    retryTimes = 20<br />    while retryTimes>0:<br />        try:<br />            return session.post(*arg)<br />        except:<br />            print '.',<br />            retryTimes -= 1<br />

  或者

  def multi_open(opener, *arg):<br />    retryTimes = 20<br />    while retryTimes>0:<br />        try:<br />            return opener.open(*arg)<br />        except:<br />            print '.',<br />            retryTimes -= 1<br />

  这样我们就可以使用multi_session或multi_open对爬虫抓取的session或opener进行保持。

  5. 多进程抓取

  6. 对于Ajax请求的处理

  它的工作原理是:从网页的url加载网页的源代码之后,会在浏览器里执行JavaScript程序。这些程序会加载更多的内容,“填充”到网页里。这就是为什么如果你直接去爬网页本身的url,你会找不到页面的实际内容。

  

  这里,若使用Google Chrome分析”请求“对应的链接(方法:右键→审查元素→Network→清空,点击”加载更多“,出现对应的GET链接寻找Type为text/html的,点击,查看get参数或者复制Request URL),循环过程。

  7. 自动化测试工具Selenium

  Selenium是一款自动化测试工具。它能实现操纵浏览器,包括字符填充、鼠标点击、获取元素、页面切换等一系列操作。总之,凡是浏览器能做的事,Selenium都能够做到。

  这里列出在给定城市列表后,使用selenium来动态抓取去哪儿网的票价信息的代码。

  8. 验证码识别

  对于网站有验证码的情况,我们有三种办法:

  可以利用开源的Tesseract-OCR系统进行验证码图片的下载及识别,将识别的字符传到爬虫系统进行模拟登陆。当然也可以将验证码图片上传到打码平台上进行识别。如果不成功,可以再次更新验证码识别,直到成功为止。

  爬取有两个需要注意的问题:

  分析

  抓取之后就是对抓取的内容进行分析,你需要什么内容,就从中提炼出相关的内容来。

  常见的分析工具有正则表达式,BeautifulSoup,lxml等等。

  存储

  分析出我们需要的内容之后,接下来就是存储了。

  我们可以选择存入文本文件,也可以选择存入MySQL或MongoDB数据库等。

  存储有两个需要注意的问题:

  Scrapy

  Scrapy是一个基于Twisted的开源的Python爬虫框架,在工业中应用非常广泛。

  Robots协议

  好的网络爬虫,首先需要遵守Robots协议。Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

  在网站根目录下放一个robots.txt文本文件(如 ),里面可以指定不同的网络爬虫能访问的页面和禁止访问的页面,指定的页面由正则表达式表示。网络爬虫在采集这个网站之前,首先获取到这个robots.txt文本文件,然后解析到其中的规则,然后根据规则来采集网站的数据。

  1. Robots协议规则

  2. Robots协议举例

  禁止所有机器人访问<br />    User-agent: *<br />    Disallow: /<br />允许所有机器人访问<br />    User-agent: *<br />    Disallow: <br />禁止特定机器人访问<br />    User-agent: BadBot<br />    Disallow: /<br />允许特定机器人访问<br />    User-agent: GoodBot<br />    Disallow: <br />禁止访问特定目录<br />    User-agent: *<br />    Disallow: /images/<br />仅允许访问特定目录<br />    User-agent: *<br />    Allow: /images/<br />    Disallow: /<br />禁止访问特定文件<br />    User-agent: *<br />    Disallow: /*.html$<br />仅允许访问特定文件<br />    User-agent: *<br />    Allow: /*.html$<br />    Disallow: /<br />    <br />

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线