python实验:网络爬虫

python实验:网络爬虫

  1. 实验目标及要求

  2. 掌握简单爬虫方法。

  3. 实验主要内容
    1 爬取中国票房网(www.cbooo.cn)2019年票房排行榜前20名的电影相关数据。
    1 请编程实现如下操作:从网址http://www.kanunu8.com/book3/6879/上爬取小说《动物农场》的所有章节;分析小说《动物农场》,按词频输出三个字的词汇前 10 项;根据词频画出这10个词汇的直方图,并另存为文件“动物农场词频.png”。

  4. 实验

    爬取中国票房网(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。

解决本题主要分为三步:

  1. 爬取不同章节html
  2. 提取html需要的内容写入txt文件中
  3. 提取词频画出直方图

爬取不同章节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安全、产品研发等方面都起着重要作用。在数据处理方面,如果没有数据就可以通过爬虫从网上筛选抓取自己想要的数据。并且伴随着网络技术的发展,我们早已进入信息爆炸的时代,面对繁冗的数据,我们很难从里面提取到有价值的数据,为了解决传统人工收集数据的不便的问题,通过利用爬虫技术就可以轻松找到自己想要的数据。在本学期的学习中虽然遇到了很多困难,通过一次次的纠正,不断地找出问题所在,最后解决问题。这仿佛是一条登山之路,比起唾手可得的成功,向上攀登的路程更加令我振奋,我相信这也是学习爬虫技术的意义之一。

  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值