第十六篇 入门级爬虫
预备知识
- 需要导入requests模块,就需要先安装这个库,在命令行中输入
pip install requests
进行软件的安装
1 爬文字
import re #导入re模块
import requests #导入requests模块
'''response是响应的意思,requests是请求的意思,这行代码就是响应爬取该网站信息的请求'''
response = requests.get('http://baijiahao.baidu.com/sid=1598724756013298998&wfr=spider&for=pc')
'''将爬取到的网页源码以文本形式接收'''
data = response.text
'''在网页源码中找到制定文字信息内容的地址,这一步需要在网页端进行操作'''
'''利用网页端提供的寻元素地址的工具来获取文字内容的地址'''
"""
<span class="bjh-p">(.*?)</span>,因为计算机对代码执行时,
会从左向右按照<span class="bjh-p">(.*?)</span>的格式搜索到地址,
(.*?)中括号里面的 点 表示每一个获取对象,可以看作是无数个省略号,
星号 表示获取所有
"""
result_list = re.findall('<span class="bjh-p">(.*?)</span>',data)
'''需要注意的是:用re模块中的findall()函数返回的值是列表类型的'''
for result in result_list:
print(result)
2 爬图片
"""导入requests模块"""
import re
import requests
'''
查看网页,分析它的分页的命名规律
http://www.xiaohuar.com/hua/ (网站首页)
http://www.xiaohuar.com/list-1-1.html
http://www.xiaohuar.com/list-1-2.html
http://www.xiaohuar.com/list-1-3.html
http://www.xiaohuar.com/list-1-4.html
......
通过分析,我们可以判断它的首页还可写成:http://www.xiaohuar.com/list-1-0.html
写成 http://www.xiaohuar.com/hua/ 有其他考虑,我们不做过多分析
综上所述,我们可以利用循环来打开它的一个个分页面
'''
"""我们可以定义一个变量来侦测爬取的情况"""
count = 0 #观察爬取情况
page = 1 #网页的页数
for i in range(page):
url = f'http://www.xiaohuar.com/list-1-{i}.html'
response = requests.get(url) #爬取整个网页的信息
"""requests是请求的意思,response是响应、回答的意思"""
data = response.text #将网页数据以字符串形式赋给data
# print(data) #打印整个网页的源码
# print(type(data)) #<class 'str'>
'''
这是在网上找到的图片路径:
<img width="210"
alt="北京大学校花肖真子"
src="/d/file/20190227/257e9f91df2bbd45c537f9416ae3afbb.jpg">
舍弃不相干的修饰(比如:图片宽度、图片名称以及包裹它们的<>符号),自行斟酌其他识别字符是否舍弃,
这次演示我们只保留src="/d/file/20190227/257e9f91df2bbd45c537f9416ae3afbb.jpg"试试
'''
"""
注意:我们在网页上复制的图片路径是无法搜寻到图片真实存储位置的,
需要依靠这条路径在编译器中对比整个网页的源码来搜寻图片的真实地址
"""
result_list = re.findall('src="(.*?)" /></a',data) #在整个网页源码中爬取所有图片的地址
"""
src="(.*?)"> 会将所有图片爬取下来,因为计算机执行代码时,
会从左向右按照src="(.*?)">的格式搜索到地址,
(.*?)中括号里面的点表示每一个获取对象,可以看作是无数个省略号,
星号表示获取所有
"""
# print(result_list)
"""
这里会找出不相干的网址路径,这是因为电脑会遵循我们设置的src="(.*?)">的描述,
找出所有符合的内容,
所以我们需要进行过滤内容的操作,可以打开一个个网页试试(很重要的过滤方式)
"""
for result in result_list: # type:str #type:str 相当于强制转换类型
# print(result) #分条查看爬取的图片地址
# print(type(result)) #<class 'str'>
if result.startswith('https'): #通过前缀判断来保留我们想要的图片的地址
# print(result)
# print(type(result)) #<class 'str'>
img_result = requests.get(result) #和response = requests.get(url)一样
img_name = result.split('/')[-1] #字符串切分之后是以列表形式存储的,所以可以用索引
img_data = img_result.content #获取图片的代码内容
# print(type(img_data)) #<class 'bytes'>
with open(img_name,'wb') as file: #注意img_name是字符串格式的变量名,可以当作文件,不需要再加引号
file.write(img_data) #将图片信息按bytes格式写入文件
file.flush()
count += 1
print(f'爬取了{count}张')
3 爬视频
import re
import requests
response = requests.get("https://www.ku6.com/index")
data = response.text #以文本的形式存储爬取到的信息
# print(data) # <class 'str'>
'''
视频在主页中所显示的图片的地址:
<img src="https://rbv01.ku6.com/wifi/o_1dab1m9bjh0o1ofc1irbof21puhg">
注意:
1、在爬取视频所在网页的地址时,我们可以通过拿到视频的图片的地址路径在编译器中对比整个网
页的源码来搜寻视频所在网页的真实地址
2、也可以在网页端通过视频的图片的地址路径来寻找,视频所在页面的寻址方式就在图片地址的上方
视频所在页面的超链接:
<a class="video-image-warp" target="_blank"
href="/video/detail?id=I3vimoOURlhSkh8AS9huWiooKyk."> # 这行就是超链接
'''
result_list = re.findall('<a class="video-image-warp" target="_blank" href="(.*?)">',data)
'''注意:这里获取的地址都是视频所在网页的地址后缀(超链接),需要接在主页地址后面才能用'''
for result in result_list:
"""通过前缀判断方法过滤不需要的地址后缀"""
if result.startswith("/detail") or result.startswith("/video"):
# print(result)
result = f'https://www.ku6.com{result}' #将超链接加在主页的后面就是视频所在页面的地址
"""这个只是到达了视频所在的页面,还包含有其他的信息,需要过滤掉"""
detail_response = requests.get(result) # 爬取视频所在页面的信息
detail_data = detail_response.text #以文本的形式接收
# print(detail_data) # <class 'str'>
'''
在视频所在页面寻找视频地址:在网页端用寻找元素的工具来点击视频,就可以找到视频地址的源码
然后对源码进行些许处理就可以放在下面的寻址函数中了
视频地址源码:
<video id="my-video_html5_api"
class="vjs-tech" style="100%;height:100%;"
preload="auto" x5-video-player-fullscreen="true" x5-video-player-typ="h5" tabindex="-1"
src="https://rbv01.ku6.com/wifi/o_1dab1luo5oao1jnk1bpnk321hevckvs"></video>
我们只需要最后面的数据,进行处理后使用:src="(.*?)"></video>
注意:如果视频网站有专题报道嵌套视频的只是稍微繁琐一点,但是思路一样
'''
'''在视频所在页面寻找视频地址'''
url_list = re.findall("src='(.*?)'></video>",detail_data)
if not url_list:
'''re模块中的findall()函数返回的值是一个列表'''
url_list = re.findall("<source src='(.*?)'></video>",detail_data)
'''<source src='(.*?)'></video>这个就是专题报道中的视频的寻址方法'''
"""这样过滤之后留下来的就是视频的地址,最后就可以爬取地址上的视频了"""
for once_video_url in url_list:
video_response = requests.get(once_video_url)
video_data = video_response.content #以字节码的形式接收爬取的内容
video_name = f"{once_video_url.split('/')[-1]}.mp4"
#video_name = f"{url_list[0].split('/')[-1]}.mp4" #不在循环中时使用
'''将获取的二进制代码信息写入文件'''
with open(video_name,'wb') as file:
file.write(video_data)
file.flush() #快速刷进内容
总结:
1 固定模式:
import requests #导入模块
import re
'''分析网页的分页情况'''
for page in range(int(page_num)):
response = requests.get('url{page}')
data = response.text
some_list = re.findall('想爬内容的网页',data) #如果是文字信息,在下一行打印即可
#......
'''分析内容所在页面的情况'''
for thing in some_list:
if thing.startswith('/辨析字符'): #过滤
sth_reponse = requests.get(thing)#如果是图片信息,可以在下一行用.content格式接收
sth_data =sth_reponse.text
somev_list = re.findall('视频地址',sth_data)
'''分析视频的情况'''
for v_url in somev_list:
v_response = requests.get(v_url)
v_data = v_response.content
'''将接受的内容写入文件'''
with open('文件名','wb') as file:
file.write(v_data)
file.flush() #快速刷入
2 寻址方式要灵活、细心
- 善于使用 . * ? 这几个字符的组合过滤掉无用信息