python实验:网络爬虫
-
实验目标及要求
-
掌握简单爬虫方法。
-
实验主要内容
1 爬取中国票房网(www.cbooo.cn)2019年票房排行榜前20名的电影相关数据。
1 请编程实现如下操作:从网址http://www.kanunu8.com/book3/6879/上爬取小说《动物农场》的所有章节;分析小说《动物农场》,按词频输出三个字的词汇前 10 项;根据词频画出这10个词汇的直方图,并另存为文件“动物农场词频.png”。 -
实验
爬取中国票房网(www.cbooo.cn)2019年票房排行榜前20名的电影相关数据。
由于原网站包含登录机制,并且点击跳转后网页url并不会产生改变,为了方便操作,我改用爬取网站2019 中国票房 | 中国票房 | 中国电影票房排行榜 (boxofficecn.com)的数据。
首先打开网页的html调试窗口,通过选择元素进行检查确定我们所需要的内容位置,为后面分析html做准备。我们发现所需内容在tbody中tr里的td中。
爬取该网站分为两个步骤:
1.爬取html
2.使用beautifulsoup中的find和find_all找到自己需要的内容。
爬取html时注意修改编码为’utf-8’,并且使用try-except判断采集是否成功,增强代码完备性。
def getHtmlDoc(url):
` `try:
` `r = requests.get(url, timeout=30)
` `r.raise\_for\_status()
` `r.encoding = 'utf-8'
` `return r.text
` `except Exception as ex:
` `print("采集错误,出错原因:{}。".format(ex))
` `return ""
使用beautifulsoup寻找html中我们需要的内容。
def getData(html, num):
` `data = []
` `soup = BeautifulSoup(html, 'html.parser')
` `tbody = soup.find('tbody')
` `# print(tbody)
` `# 获取下面所有的tr
` `for tr in tbody.find\_all('tr', limit=num+1):
` `# print(tr)
` `each\_data = []
` `for td in tr.find\_all('td'):
` `# print(td.text)
` `text = td.text
` `each\_data.append(text)
` `data.append(each\_data)
` `return data
num为我们需要排名前几的电影数据,本题中我们的num为10,通过find_all中的limit限制提取数据数量。最后输出列表data
完整代码:
import time, requests, jieba
from bs4 import BeautifulSoup
from wordcloud import WordCloud
import numpy as np
def getHtmlDoc(url):
` `try:
` `r = requests.get(url, timeout=30)
` `r.raise\_for\_status()
` `r.encoding = 'utf-8'
` `return r.text
` `except Exception as ex:
` `print("采集错误,出错原因:{}。".format(ex))
` `return ""
\# num为爬取前几的电影数据
def getData(html, num):
` `data = []
` `soup = BeautifulSoup(html, 'html.parser')
` `tbody = soup.find('tbody')
` `# print(tbody)
` `# 获取下面所有的tr
` `for tr in tbody.find\_all('tr', limit=num+1):
` `# print(tr)
` `each\_data = []
` `for td in tr.find\_all('td'):
` `# print(td.text)
` `text = td.text
` `each\_data.append(text)
` `data.append(each\_data)
` `return data
\# 主程序
url = 'http://www.boxofficecn.com/boxoffice2019'
all\_data = []
html = getHtmlDoc(url)
\# print(html)
all\_data = getData(html, 10)
all\_data[0] = ['序列', '年份', '电影', '票房(万元)']
print(np.array(all\_data))
print("电影数据已爬取")
运行结果:
请编程实现如下操作:从网址http://www.kanunu8.com/book3/6879/上爬取小说《动物农场》的所有章节;分析小说《动物农场》,按词频输出三个字的词汇前 10 项;根据词频画出这10个词汇的直方图,并另存为文件“动物农场词频.png”。
为了自动化爬取全部章节的内容,我们需要分析这些章节url之间的规律,以便使用代码自动化爬取html。
通过观察我们发现不同章节url前面的内容都是
https://www.kanunu8.com/book3/6879/
不同章节从后面添加后缀,第一章为131779.html,第二章为131780.html,我们发现就是不断加1。于是通过循环控制url。
解决本题主要分为三步:
- 爬取不同章节html
- 提取html需要的内容写入txt文件中
- 提取词频画出直方图
爬取不同章节html并将find所需内容写入txt文本文件中
import time, requests, jieba
from bs4 import BeautifulSoup
from wordcloud import WordCloud
import numpy as np
def getHtmlDoc(url):
` `try:
` `r = requests.get(url, timeout=30)
` `r.raise\_for\_status()
` `r.encoding = 'gbk'
` `return r.text
` `except Exception as ex:
` `print("采集错误,出错原因:{}。".format(ex))
` `return ""
\# num为爬取前几的电影数据
def getData(html):
` `data = ''
` `soup = BeautifulSoup(html, 'html.parser')
` `table = soup.find\_all('table', width="880", border="0", align="center", cellpadding="0", cellspacing="0")
` `for each\_table in table:
` `# print(table.index(each\_table))
` `if table.index(each\_table) == 4:
` `p = each\_table.find('p')
` `data = p.text
` `# print(data)
` `return data
\# 主程序
url = 'https://www.kanunu8.com/book3/6879/'
all\_data = []
for i in range(131779, 131789):
` `new\_url = url + str(i) + '.html'
` `html = getHtmlDoc(new\_url)
` `# print(html)
` `data = getData(html)
` `all\_data.append(data)
print(np.array(all\_data))
print("动物农场已爬取")
Note = open("爬虫文章.txt",mode='w')
for i in all\_data:
` `Note.write(i)
Note.close()
已经写入文本文件中
提取词频并画出直方图
代码:
import jieba
def getText(filepath):
` `f = open(filepath, 'r', encoding='gbk')
` `text = f.read()
` `f.close()
` `return text
def wordFreq(filepath, text, topn):
` `words = jieba.lcut(text.strip())
` `counts = {}
` `stopwords = stopwordslist('hit\_stopwords.txt')
` `for word in words:
` `if len(word) == 1:
` `continue
` `elif word not in stopwords:
` `counts[word] = counts.get(word, 0) + 1
` `items = list(counts.items())
` `items.sort(key=lambda x:x[1], reverse = True)
` `f = open(filepath[:-4]+'\_词频.txt', 'w')
` `for i in range(topn):
` `word, count = items[i]
` `f.writelines("{}\t{}\n".format(word, count))
` `f.close()
def stopwordslist(filepath):
` `stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
` `return stopwords
wordFreq('爬虫文章.txt', getText('爬虫文章.txt'), 50)
我们看到已经提取了词频,前面的几个词主要是动物、庄园、拿破仑等
画出直方图
代码:
import matplotlib.pyplot as plt
lis\_score = []
plt.rcParams['font.family'] = ['SimHei']
plt.title("词频直方图")
x = ['动物', '庄园', '拿破仑', '斯诺', '同志', '鲍克瑟', '琼斯', '风车', '先生', '克拉']
height = [427, 212, 172, 132, 94, 93, 85, 81, 51, 44]
plt.bar(x, height)
plt.xlabel("词汇") # 设置x轴标签
plt.ylabel("出现次数") # 设置y轴标签
plt.xlim(0, 10) # 设置x轴区间
\# plt.xticks(range(1, 10)) # 设置x轴刻度
plt.yticks([0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500]) # 设置y轴刻度
plt.grid()
plt.show()
运行结果:
实验心得
众所周知,Python涉及的领域非常之广。大数据,人工智能,机器学习,网络爬虫等等一些当今世界尖端领域,Python都在其中充当着一个不可替代的角色。这次实验我们就学习了Python爬虫。
爬虫实践中使用两大系统:
1.比较简单的爬虫:使用Java直接从接口维度来获取数据。
2.对于反爬比较厉害的:通过puppetter来模拟浏览器来访问页面来获取数据。
爬取数据的步骤
先不考虑反爬,一般的爬虫过程是这样
1.找到目标网站的url
2.模拟发送请求url,获取html数据
3.解析html指定节点来获取我们想要的数据。
无论你是使用python,还是java,还是其他语言,都可以简单的实现,来获取巨大的成就感。
对于不同的网站,由于我们想要的数据以及网站html的格式不一样,上面的第三步,我们都必须对不同的网站写不同的解析代码来完成,如果你仅仅需要爬几个网站,你可能会乐此不疲的一个一个这样做,看到页面数据被打印到屏幕上,就很开心。
如果要爬取100网站呢?如果你依然这么干,那就是一个体力活了。
所以,如果要持续的爬取不同的网站,这也是比较痛的一个点,如果爬取的网站数量会持续增加,可以考虑通过配置化selector来解决。
爬取数据的意义
另外要说的一点就是:单纯的爬取一个又一个数据是没有任何意义的,有意义的地方在于:通过对爬取的数据进行数据分析,才是其意义所在。
举个简单的例如:你想买一个airpods,如果你仅仅把各大网站airpods的商品信息(包括价格)爬下来了,不做任何处理,躺在数据库里这是没有任何意义的。而如果我们把airpod在各大电商平台的价格变化趋势监控起来,然后进行比对分析,在低于某个价格点的时候给你发通知去购买,这样是不是就变的有意义了。
所以,数据爬取仅仅是完成了一小步,要使爬下来的数据变的有意义,还有更多的事情要去做。
关于反爬,如果目标网站没有反爬的话,我们就很容易的爬取我们想要的数据,但是对于大型网站,例如:淘宝拼多多之类的,反爬是存在的,而且对于不同的数据,他们的反爬手段和程度是不一样的。
如果你对某目标网站,仅需爬取少量的数据,且频率不高,例如:每个月一次,那么也不存在反爬的问题。
最后,是关于境外网站数据的爬取:你可能想爬下twitter的数据玩下,你就需要搭建一套境外服务器了,然后和上面的步骤一样来爬就可以了。
作为一名计算机科学与技术专业的学生,经过一学期的网络爬虫学习,我意识到在生活中或是未来工作中,网络爬虫是我可以利用的一种高效工具。网络爬虫技术在科学研究、Web安全、产品研发等方面都起着重要作用。在数据处理方面,如果没有数据就可以通过爬虫从网上筛选抓取自己想要的数据。并且伴随着网络技术的发展,我们早已进入信息爆炸的时代,面对繁冗的数据,我们很难从里面提取到有价值的数据,为了解决传统人工收集数据的不便的问题,通过利用爬虫技术就可以轻松找到自己想要的数据。在本学期的学习中虽然遇到了很多困难,通过一次次的纠正,不断地找出问题所在,最后解决问题。这仿佛是一条登山之路,比起唾手可得的成功,向上攀登的路程更加令我振奋,我相信这也是学习爬虫技术的意义之一。