爬虫-》 (又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
那么重点来了,就是自动抓取信息
有些人,想试试爬虫,但是看着太复杂,代码太多,就觉得不想弄了。然而其实爬虫代码前篇一律,我这里就非常简单的讲一下爬虫。
总结来说,步骤就是 请求服务器-》获得响应信息-》信息解析-》信息存储
我这里讲的是python爬虫哈
1.发送请求
请求
首先我还是扯出来一段代码:(当然你copy运行后还是乱码,因为还没解析)
import requests
r = requests.get('http://www.baidu.com/')
print("文本编码:",r.encoding)
print("响应状态码:",r.status_code)
print("字符串方式的响应体:",r.text)
我们把互联网比作一栋楼,而我们要爬的网站,就是那些住户,每个住户呢都有自己的门牌号(URL)。发送请求呢就是输入门牌号还有自己的身份标识(这段代码没有加上自己的身份标识,有些网站会判断你的身份就需要了)然后请求住户同意。
那么我们这里用的是requests这个python的包(提前安装)
这里讲下得到的 r 的内容:
r.text 服务器响应内容,自动根据响应头部的字符编码进行解码,
其实就是网站给你呈现的内容。
r.encoding 服务器内容使用的文本编码
r.status_code 检测响应的状态码,200为成功 4xx为客户端错误
5xx为服务器错误响应
r.content是字节方式的响应体,会自动解码gzip和deflate编码的响应数据
r.json()是request内置的json解码器
这个呢只是简单的请求,也就是我们照着门牌号去敲门,而有些网站就会说:不是什么人都能来拜访我的。那么我们就需要一个身份标识也就是传递一个请求头。
定制请求头
#定制请求头
import requestslink = "http://www.baidu.com"
headers = { 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
'Host':'www.baidu.com'
}
r = requests.get(link,headers = headers)
print("响应状态码:",r.status_code)
这个代码里面的 headers 就是所谓的请求头,里面可以加很多信息,具体的可以在浏览器看到,比如 打开百度,然后按 F12 你可以看到右侧会弹出来一个方框:
然后点击network,并在左栏中找到www.baidu.com,并下划看到 requests headers:
然后这一堆就都是你作为浏览器进入这个网站的标识符了。一般写爬虫都得带个头,保险嘛。
设置等待时间
有时候吧,你网络不行,你这个爬虫呢就一直在门口等着,那住户不开门就不走,你就会发现你的爬虫一直运行但是没数据(其实requests有默认等待时间),所以还得加个每次请求的等待时间:
r = requests.get(link,timeout = 20)
(当然这里用的get 其实还有post等其他请求方法这里不多说。)
获取数据
那,其实请求成功了,就如上面得到的 r 里面就已经是你得到的数据了。也就是住户已经给你资料了。
解析数据
所以重点在解析数据了。我们拿到了资料,但是里面一堆乱码,而且还很多多余的字母,所以我们想把它解析出我们想要的,这个时候美丽汤(BeautifulSoup)出现了,它给我们提供了一个有效的解析方法。
总结一下就是:
soup = BeautifulSoup(response.text, features='html.parser')
这里的response.text 其实就是我之前赋值的 r ;features就是解析方式,一般用lxml
soup.find('div') #返回符合div的匹配段
soup.find(id='1') #返回符合id = 1的匹配段
soup.find('div', id='1') #返回符合div 且 id = 1 的匹配段
然后find_all 就是找到所有匹配的。
这里的div id 其实就是一个个标签,你打开F12的时候,网页里面的element会看到很多 div h1 h2 啊啥的 然后后面还会跟着一堆东西,这些涉及前端的知识我就不多讲,你可以把它们当作一个名字前缀,然后find 和find_all 就是按照你输入的前缀来查找符合标准的前缀数据。
那这里有个筛选方法,比如豆瓣影评里面的,你点一下这个符号
也就是F12右框左上角的那个箭头符号,然后再指向你想筛选的个例,比如影片题目,然后点一下:
右侧就会标志出对应的内容,那么我们就可以这么筛选:
soup = BeautifulSoup(r.text,"lxml")#记得安装lxml
div_list=soup.find_all('div',class_='hd')#class下加下划线
也许你会问,为什么不是 span class_ =‘title’,这里讲为什么就比较多了,所以就这么说,div就是一个范围的标签,这里的find是需要从范围入手,然后class就是div内的一个小框,要找到span class = ‘title’ 的话首先得找到它的最小div 然后是class最后才一步步递进,也就是接下来的操作:
# movie_list是一个空列表,专门存放电影名字。
# strip()函数是去除字符串两端的字符,
for each in div_list:
movie = each.a.span.text.strip()
movie_list.append(movie)
这里的div_list 就是我们找到的范围,由于用的find_all 所以返回的范围里会有多个class在里面,我们就要用for 一个个筛选,也就是一层层的上面的图片你也看到了,是一层层范围包裹下来:
所以我们也是 each->a->span,然后通过strip去除两端字符,然后并入list里面。
存储数据
存储数据的话就用numpy 的savetxt()就行了。具体存储这里就不讲了。
这里就只是简单的讲讲,如果有什么疑问请留言哈。
这里就给个爬豆瓣的例子:
import requestsfrom bs4
import BeautifulSoup
link = "https://movie.douban.com/top250"
#定义翻页函数
def get_movies():
headers = { 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',#别忘了逗号
'Host':'movie.douban.com'
}
movie_list = []
for i in range(0,10):#别忘了,冒号
link = 'https://movie.douban.com/top250?start='+str(i*25)
r = requests.get(link,headers = headers,timeout = 10)
print(str(i+1),"页响应状态码:",r.status_code) #解析
soup = BeautifulSoup(r.text,"lxml")#记得安装lxml
div_list=soup.find_all('div',class_='hd')#class下加下划线
# movie_list是一个空列表,专门存放电影名字。
# strip()函数是去除字符串两端的字符,
for each in div_list:
movie = each.a.span.text.strip()
movie_list.append(movie)
return movie_list
movies = get_movies()
print(movies)
(复制粘贴的有问题我没试过,有问题请留言)