Python手记(一):实现简单爬虫过程中的坑(urllib)

人生无趣,一起来找点乐子吧。欢迎评论,和文章无关的内容也没关系。

 

 

不知道大家知不知道,在交互环境IDLE下输入import this,就会打印出《Python之禅》:

像个彩蛋~,这应该算是所有玩python的人的信仰与追求吧。

 

话不多说,前几天写了一个简单爬虫,虽然代码没几行,但是遇到的问题不少。在这里简单示例的总结一下。也希望能对其有兴趣的朋友一些帮助。

python第三方模块很多,你可以选择你喜欢的,我这里只是单一的介绍一种。

 

(一)

先来看一下怎样获取到一个网页的信息内容。

这里我先用urllib来谈下(因为requests的出世,已经很少人直接用它了),你可以在cmd中执行pip install 去安装它。你也可以直接 pip install requests,requests之后会用到,而且同时也会把urllib安装好。(建议大家用python3.6)

首先你先要获得你想的得到的网页的url,也就是网址,我们这里以百度为例。https://www.baidu.com/

代码如下:

import urllib.request

url = 'https://www.baidu.com/'
request = urllib.request.urlopen(url)
html = request.read().decode('uft-8')
print(html)

urllib.request.urlopen函数的参数要传递一个网址,返回给变量request,然后调用read()函数,读出数据,decode是编码方式。如果不写默认是utf-8。

运行之后你会得到这么条信息:

我们感觉百度界面有很多东西,但是看到才这么几行标记语言的代码,很不对等。这里其实是因为网页上的内容都是动态生成的。什么意思呢?简单解释下,类比变量吧。我们撸代码的时候,定义了个变量,如果print输出,我们并不是输出这个变量的名字或是一个固定值,变量赋值什么,输出就是什么。

在网页上,我想要显示的数据也不直接显示出来,而是通过后台给我数据,我再将数据显示出来。

拿CSDN主页来说,顶部就是一个消息栏,一张张的照片自动切换,发布着不同的消息。如果将数据直接写进html里,当我需要更新消息的时候,就必须重写网页了。相反如果网页的数据是动态生成的,网页的变量由数据库的数据决定。那我只需要更新数据库,网页也就会相应的改变了。

 

(二)

现在我们得到了网页信息(大家至少要对标记语言有些了解,但不会太影响到下面的内容,如果看不太懂了就去查下),接下来获得我们需要的信息。因为百度主页没啥东西的原因,这里我们把网址换成csdn的主页https://www.csdn.net/。

执行完毕后是不是震惊了,好多数据啊。择其一,大约在这里,有个img

我们请求那个连接,发现是:

也就是我们网页的这里

好,我想要这张图片。

上段代码中的html变量,其实是str类型,也就是说,你获得这些东西,完全可以当成字符串处理,去获得那个img。我们网页中有太多的标记(或者称为标签)。<img><head><p><body>等等,这些字符串处理是很难得。

我们用到了另一个模块,beautifulsoup,专门用来处理网页信息。cmd下安装:pip install bs4。

代码如下:

import urllib.request

from bs4 import BeautifulSoup

#获得信息
url = 'https://www.csdn.net/'
request = urllib.request.urlopen(url)
html = request.read().decode()

#处理信息
bs = BeautifulSoup(html,'html.parser')
img = bs.find('img')
print(img)

调用beautifulsoup函数,第一个参数就是你刚刚获得的一堆东西(str)。让beautifulsoup全部吞掉,后一个参数是处理的方式。有四种,可以处理大多数前端语言。(大家感兴趣可以去下查其他的,并看看区别所在。)

我们要获取<img  **************>这个东西,我们可以看到我们要的img是网页中的第一个img,这里调用bs对象的find方法,参数就是你要获取的标记。他就会返回第一个,如果你想获取网页上所有的img呢?那就调用find_all( )函数,他就会返回所有的img。输出:

得到的还不是我们想要的,我们只要img标签里src的内容。ok,print(img) 换成 print(img['src'])

成功。(bs对象的方法有很多,能够实现各种各样的功能,感兴趣可以去详细学习。)

 

(三)

接下来就是下载图片。(很有趣哦,下载歌曲,下载视频也都是同样的原理!)

我们现在得到了新的url,但他不是标准的url,在使用前,将其补全https://**********

当然视情况而定,获得的url不一定全是残缺的。

这里涉及到文件的内容。简单提下:例 f = open('','') 。open函数会返回一个指针。函数的两个参数,第一个,文件地址,或者说路径,第二个参数是 打开方式。w(写) r(读) b(二进制数据) a(追加)等等

代码如下:

import urllib.request
from bs4 import BeautifulSoup

#获得信息
url = 'https://www.csdn.net/'
request = urllib.request.urlopen(url)
html = request.read().decode()

#处理信息
bs = BeautifulSoup(html,'html.parser')
img = bs.find('img')

#下载图片
url = 'https:'+img['src']
picture = urllib.request.urlopen(url).read()

f = open('F:1.jpg','wb')
f.write(picture)
f.close()
'''
可以替换前面三句
with open('F:1.jpg','wb') as f:
    f.wirte(picture)
'''

前面相同,我们获得网页的内容,然后打开文件,F盘下的1.jpg文件。如果没有怎么办呢?不用担心,因为我们打开的方式是‘wb’,w是write,b是binary,也就是以二进制的方式写入,写入的时候,如果找不到文件,就会自动创建。(如果有1.jpg图片的话,你执行完,那张图片就被覆盖了!)

然后,f.write( )将picture写入1.jpg,记得一定要close()。我们可以把它理解为我们在写完东西后随手点的“保存”。如果不写,那就相当于直接点右上角的xx了。

with as的是另一种文件打开的表达方式,和上面的三句功能完全相同。但明显简单不少,区别在于,在执行完with内部语句后,会自动帮你close,所以尽量习惯去用with open,避免自己忘记保存。(python的魅力啊~)

执行完,去我们选择的路径下,看到了

打开查看一下

还行~

用这种方法你可以去得到你想要的东西。mp3音乐文件,mp4视频文件等等,其余都相同,就是记得写入的文件一定要是.mp3或者.mp4拓展名,才能执行。这张图片是.jpg的,通过url你可以看到他的拓展名是什么,写入的文件最好和其相同。

(如果爬的数据较多,记得巧妙运用循环哦)

 

这里说一点,计算机上的文件,我们大的分就两种——文本文件和二进制文件。简单点理解,文本文件是给人看的,二进制文件是给计算机运行的。我们经常用的exe就是二进制文件,还有图像,声音等等,这些都是二进制文件,计算机可以直接运行。文本文件是基于字符编码的文件,最简单的就是txt了,我们经常有事没事就新建一个文本,有事没事就删除一个。

 

(其实你要爬东西,难点根本不在怎样将数据写入文件,而是怎样找到资源的链接。就好比我们想要那张图片,怎样得到图片的url是一样的。这个需要我们大量的前端知识,前端知识越深,你能找到的东西越多,能免费享用的东西也就越多~)

—————————————————————————————————————————————————————

 

以下是一些特别情况的应对措施:

 

import urllib.parse
key = urllib.parse.quote(name)   

解析url编码,可以用于一些搜索。将汉字等数据进行url编码,比如在百度‘xx’后,浏览器网址变成了xx,其实不然,当点击地址框时,真正的地址并不是汉字,里面的类数字编码,就可用此函数对汉字进行编码。

比如我们百度“百度”,可以看到地址栏的链接wd=百度,我们把链接复制下,写到文本文件里看看(截取一小部分):

https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6

我们看到wd后面根本不是汉字“百度”,而是汉字的url编码。上面的方法就可以将汉字转成这种url编码:

可以看到和链接里的编码是一模一样的。

 

 

import json
jd = json.loads(html)
print(jd['data']['song'])    

处理json文件(一种基于键值对的信息存储文件,理解成python里的字典也没关系),loads函数的参数是str类型(和html一样,把得到的json文件的内容直接给loads,loads可以将json类型转成dict类型,然后就可以直接引用了。),对象jd数据就可以直接理解成字典来使用,类比BeautifulSoup,bs专门处理标记语言,json就专门处理json数据。总比拿字符串自己处理强啊。

 

伪装爬虫:

url = ""
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                        'Chrome/51.0.2704.63 Safari/537.36'}
req = urllib.request.Request(url=url,headers=headers)
 
res = urllib.request.urlopen(req)
 
data = res.read()

很多网站有反扒系统,检测到你是爬虫,就会给你返回错误或者空白。比如,当你用浏览器请求某个网站的时候,可以正常打开,但是当用代码去请求网站是,返回错误(或者空白消息),这就是反爬被触发了。发送的请求里,有请求头head这么个东西存在,其实就是存放了一些请求的信息,比如告诉某服务器我是个‘浏览器’等等的身份信息也会存到这里面。用代码发送的请求的身份信息是python程序,服务器就拒绝了。所以,请求之前,改掉自己的head,带个别人的帽子,他就认不出你来了(嗯,穿上马甲他就不认识你了)。原理就是这样,怎样理解就看你喽。

        Thanks for watching.

 

 

后记:

这篇文章写作时间略早(我竟死皮赖脸的敢说我这是写作......),urllib的出现也比requests要早。不能说requests比urllib好多少,功能上基本都能实现,但是requests就是要比urllib流行的多。如果这篇文章足够您玩,则以。如果不太行,还需要些其他的详细内容,可以审看这个系列的requests写爬虫,我在里面更多的介绍了一些基础知识,最后用爬虫写了个翻译器。

说这么多,我只是自恋的以为——文人傲骨。(臭不要脸~,笑)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值