教你写只爬虫


        在从零开始教大家写个小爬虫前先说一说爬虫是什么东西吧,百度就不百度了,想把我所认为的爬虫给大家说一下吧


        以前学爬虫之前觉得爬虫感觉好牛逼的样子,认为这东西和骇客差不多似的,偷取别人信息。其实学完之后慢慢思考下,我觉得爬虫就是一段脚本程序,作用就是用来模拟人类的上网的行为、进而代替人类去手机网站上面的信息。免去人类在网站上面收集信息的无聊。当然爬虫也可以用非脚本语言写,参考这篇文章。这算是我第一次写爬虫程序吧,用的是java语言。毕竟当时自己是认真学习java以后混饭吃的嘛。


        后来学习爬虫就初识python,废话不多说了,这篇文章我就当你有点py基础的人来写爬虫,不想对一些东西做详细讲解。因为我喜欢短小精悍的文章奋斗



如何写爬虫


        今天这个爬虫就是用来爬取百度图片的,我会把怎么写的过程详细给大家从头说一遍。<感觉不太现实,这爬虫还是去年写的都记不得了>


        打开百度图片的首页,输入“河智苑”查找就能展示女神河智苑的很多图片了吧。



        查看女神图片之前,先在网址的后面加上/robots.txt,<https://image.baidu.com/robots.txt>回车查看百度图片robots的协议。可以在任何网站后面加上这个后缀去查看这个网址的robots协议,如果没有则表示默认可以爬取该网址的所有信息。如果被网络管理员举报了,在法律上应该不会判你违法,毕竟没有就表示默认爬取所有信息嘛。


        

        我们看一下这个一些内容,学过html的你应该感觉这有点像,像那啥是吧。没错,网页标签的属性。上面说了什么什么可以爬取<Allow>,什么不可以爬取。但是今天我们就不看了,做为教学加上我们这个只是小爬虫不会对百度服务器和流量有什么影响的。李彦宏大boss应该不会和我有啥计较的嘛。


        查看女神图片后,鼠标右键查看网页源代码或者F12键。我们这里就F12键吧,界面现在是这样的。




        

        右上边是网页的标签代码,然后有个箭头的图片,点一下之后将箭头图标放在左边一个图片上面在鼠标左键按一下就行了。这时候我们看到了这张图片在这个网页代码中的位置啦。



        图片在网页中用<img>标签表示,src属性是图片的路径所在地,我们可以验证一下,双击src中的https内容便可以自动选中,复制一下网址在新的空白网页输入查看图片。



        没错。这张图片是通过https协议存储在远程服务器中的,有了网址就可以找到服务器中对应的图片,然后将其下载到本地。



实现爬虫

        OK,接下来介绍一下今天这只爬虫如何工作。首先用requests将网页代码拿过来,然后我们在网页中提取图片下载链接<https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2613968603,1703511776&fm=27&gp=0.jpg>就是这样的。在一个文本文件中如何提取特定字符串,可以用到正则表达式。头大了,写正则表达式就是很头疼,如果在html文档中提取标签属性的属性值可以用到一个python库,号称美味汤的库BeautifulSoup4。


        不过这又要开始讲解这个库了,麻烦、我懒得讲,用正则匹配吧。

URL":"([^"]*\.jpg)".*?,


        我写好了你们就不用写了,当然你可以不看自己写。推荐一个工具Regex Match Tracer,专门用来写正则表达式的,很不错的软件,超级小。


        将代码中的图片路径存储在python的list类型列表中,用requests下载器下载下来用os库写入到本地磁盘就行了。



代码讲解

        首先用pip包管理工具下载第三方的requests库,然后导入requests库和本地自带的os读写库以及正则表达式re库,一共三个库。


        方法getHTMLText是通过requests请求将网页源代码获取返回来,输入参数就是url链接;但是大家可以看这个方法中的url不是链接是我们要搜索图片的关键字。


        

        没错,我们写代码不可能让用户去输入链接,所以我们把真实的链接放在方法中了。然后用try except来捕获异常,这样防止用户在键盘上瞎按导致百度没有这个关键字的图片。

<你永远也不知道用户是不是人尴尬>



        方法parsePage就是将网页的代码,我们看作是一个很长很长的str类型的字符串。用我们的正则表达式在网页中匹配图片下载地址,然后将下载地址存储在list列表中。当然为了避免爬的时候网速出问题爬不下来报错我们也try一下。


        方法pictureSave就是将list列表中存储的图片下载地址通过requests下载器和os读写库下载到本地磁盘就行了,我把图片保存到来电脑D盘的zzzzz文件夹中,没有这个文件夹也没关系,会自动帮你生成。不过我无聊加了一点点功能,防止哗哗哗哗哗哗的一直下,下到百度图片库没图了或者本地磁盘存爆停止,太可怕了。所以加了一个一次一次下载的功能,每次你想下载多少张就自己输入数字,请不要输入小数或abc。一次下载完之后是否继续下一轮的下载看你自己意愿辣。


        方法main就是我自己定义的主函数来调用上面方法的,不是c++、java中的那种main函数,两者不一样。代码中的main()这行才是真正运行的。



import requests
import os
import re


def getHTMLText(url):
     try:
          url = '''https://image.baidu.com/search/index?tn=baiduimage&ipn=
               r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=11
               1111&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&he
               ight=&face=0&istype=2&ie=utf-8&word='''+ url
          r = requests.get(url,timeout=30)
          r.raise_for_status()
          r.encoding = r.apparent_encoding
          return r.text
     except:
          print("爬取网页失败辣")
          return ""


def parsePage(ilt, html):
    try:
         p = r'URL":"([^"]*\.jpg)".*?,'
         imglist = re.findall(p,html)
         for i in imglist:
              ilt.append(i)              
    except:
         print("爬取图片连接出错辣")


def pictureSave(ilt):
     j = 1
     n = 0
     n = input('请输入默认一次爬取多少张图片:')
     for i in ilt:
          url = i
          root = "D://zzzzz//"
          path = root + url.split('/')[-1]
          try:
               if not os.path.exists(root):
                    os.mkdir(root)
               if not os.path.exists(path):
                    r = requests.get(url)
                    with open(path,'wb') as f:
                         f.write(r.content)
                         f.close()
                         print('第{}张图片保存成功'.format(j))
                         j=j+1
                         #print("文件保存成功")
               else:
                    print("第{}张图片已存在".format(j))
          except:
               print("爬取图片失败")

          if(j%int(n)==0):
               print('\n已经爬取{}张照片'.format(n))
               ch = input('是否继续爬取(Y/N):')
               if(ch=='Y'or ch=='y'):
                    n = int(n)+int(j)
                    continue
               elif ch=='N'or ch=='n':
                    print('爬取结束')
                    return
               else:
                    exit


def main():
     url = input('请输入要爬取的关键字:')
     infoList = []
     #pic = getHTMLText(url)
     html = getHTMLText(url)
     parsePage(infoList,html)
     pictureSave(infoList)


main()



        我想该输入什么关键字呢?当然是我女神河智苑啦!以后再也不用自己在百度一张一张的下载了。当然,如果你

想下载一些不可miao shu的图片请正确输入你的关键字<雪桐老司机突然开始飙车辣得意>。


        难得写一篇关于py爬虫的,就再多瞎BB一些吧。一般爬虫寿命很短,有的比较特别,例如我这只。去年6月份写的,到现在10个月了还能用。可惜我们学校的图书馆网页信息一个暑假就换了一次尴尬



爬虫素质

        爬虫不管是大是小都会给别人服务器有影响的,所以以后写爬虫一定不要考虑自己的信息收集速率,还要考虑别人的服务器。爬跨别人的服务器是非常非常不道德的事情,人神公愤。可以建议大家看一篇文章,题目好像叫《做一个有素质的爬虫》,再看看一些其他人写的爬虫心得,如何减少对别人服务器的影响也不明显降低自己信息采集速率。


        就像文章前面说的那样,我认为爬虫是模仿人在网站上收集信息的。确切的说应该是模仿你自己,爬虫的素质就代表了你的素质


        不写了,室友喊我吃鸡啦。




猜你喜欢

转载自blog.csdn.net/m0_37713821/article/details/80487552