无聊的时候,咱们总会打开豆瓣电影榜,从上到下刷着电影,仿佛那些经典台词立刻就在咱们耳边响起,如《肖申克的救赎》中:生活能够归结为一种简单的选择:不是忙于生存,就是赶着去死;《霸王别姬》中:说的是一生!差一年,一个月,一天,一个时辰,都不算一生!可是,豆瓣电影那么多,还有那么多页,一页一页的找岂不是太费时间了,今天我就来从前端的角度来爬取豆瓣电影榜top250的首页。豆瓣top250javascript
因为咱们须要向豆瓣的服务器发送一个请求来获得豆瓣首页的html代码,请求与响应在网络传输中须要必定的时间,然后续的操做须要在这个响应的基础上进行,所以,咱们须要将主函数定义为异步的。以上实现须要引入下面两个包(注意:request 是对等依赖,须要与request-promise 分开安装)html
npm i request
npm i request-promise
复制代码
let request = require('request-promise')
const main = async() => {
let html = await request({
url: 'https://movie.douban.com/top250'
})
console.log(html)
}
main();
复制代码
这样,咱们就获得了豆瓣首页的html代码,可是咱们须要的只是不多的一部分信息,因此咱们要对其中的信息进行提取,所以咱们引入一个npm包cheerio来提取html 特定选择器中的文本内容前端
npm i cherrio
复制代码
而后在第二行引入java
let cheerio = require('cheerio');
复制代码
接下来咱们要作的就是利用cheerio 将获得的html文本载入内存构建DOM,并使用选择器对目标标签中的文本进行提取,所以咱们须要分析豆瓣首页的html结构node
根据上面咱们对结构的分析,咱们就可使用下列语句获得咱们选择器内的每个itempython
let movieNodes = $('#content .article .grid_view').find('.item');
复制代码
而后咱们对保存了全部item的这样一个数组遍历,将其中每一项的关键值提取出来并保存,选择器的构建方法与上述的item得到的方法一致npm
let movies = [];
for (let i = 0; i < movieNodes.length; i++) {
let $ = cheerio.load(movieNodes[i]);
let titles = $('.info .hd span');
titles = ([]).map.call(titles, t => $(t).text());
let bd = $('.info .bd');
let info = bd.find('p').text();
let score = bd.find('.star .rating_num').text();
movies.push({
'titles': titles,
'info': info,
'score': score
})
}
复制代码
不一样的是,因为.hd 的选择器下面有四个span,所以咱们获得的是一个对象数组,咱们不能直接进行提取不然会出现对象循环引用的错误,咱们先使用map对空数组的每个元素进行映射,而后再经过改变this指针,使用选择器对空数组中每个元素进行赋值。而后将提取出来的每个字段append到数组中。编程
接下来,咱们在第三行加上json
let fs = require('fs');
复制代码
在for循环的外面继续补充api
fs.writeFile('./mainjs.json', JSON.stringify(movies), 'utf-8', (err) => {
if (err)
console.log('写入失败');
else
console.log('写入成功');
});
复制代码
就能够将咱们刚刚在存在数组中的数据以json格式写入文件中啦,打开这个文件就会发现豆瓣top250的首页内容就存到了这个文件中,咱们就能够挑选本身喜欢的电影观看了。 如今,让咱们回过头来看看豆瓣top250首页的页面结构
经过对豆瓣的爬取,咱们知道了,若是一个网站的结构带有必定规律,并有良好的可读性,会让咱们的爬取更加简单,相反,若是一个网站乱糟糟的,毫无章法可言,那么这样的网站简直就是灾难。所以,咱们在从此的编程中,应当多看看一些大型网站的html代码,学习其中的结构设计和命名规范。而后咱们可使用BEM(Block Element Modifier)命名规范,对每个模块使用合适的选择器,这样不只提升了代码的可重用行,也利于网站的管理和维护。 暑假闲来无事看了点python视频,虽然已经忘得都差很少了,可是用了node爬取了一次,又让我又拾起的对python的热情,因而一番折腾,查了相关文档,终于给捣鼓出来了,毕竟,生命在于折腾嘛! 如下是python的爬虫方式,基本思路与上述爬虫方式相似,只是对数据处理的语法上有所差别:
须要安转requests和beautifulsoup4模块
pip install requests
pip install beautifulsoup4
复制代码
import requests
from bs4 import BeautifulSoup
import json
def gettext(x):
return x.get_text()
#设置请求头假装
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
# 先使用requests发送网络请求从而获取网页
html = requests.get('https://movie.douban.com/top250', headers=header)
# print(html.status_code)
# 传入html构建DOM
soup=BeautifulSoup(html.content,'html.parser')
movieNodes = soup.find('ol', attrs={'class': 'grid_view'})
movies=[]
for movie in movieNodes.find_all('li'):
title=movie.find('div',attrs={'class':'hd'})
titles=title.find_all('span')
titles1=map(gettext,titles)
tit=[]
for ti in titles1:
tit.append(ti)
info=movie.find('p').get_text()
score=movie.find('span',attrs={'class':'rating_num'}).get_text()
movies.append({
"titles": tit,
"info": info,
"score": score
})
f = open("mainpy.json", "w", encoding='utf-8')
json.dump(movies, f, ensure_ascii=False)
f.close()
复制代码
可能有时候写程序就是这样,出一个问题而后你就去解决这个问题,而后又出现另外的问题,你又得想怎么去解决新出现的问题,而后一直一直....结果发现直接使用一个api就行了...可是写程序注重的是过程,bug是咱们编程道路上的补品,咱们不能作一个apier,不是吗?