Python爬虫+简易词云的制作
写在前面再识Python简介:应用场景:Python命令行执行:基本语法:连接数据库:Python爬虫主要步骤:第一种爬虫:urllib基本库+Beautiful SoupurllibBeautiful Soup第二种爬虫:Scrapy+xpathScrapyxpath简易词云写在前面
这篇博客是我在大连参加实训时所作,大部分内容为课堂知识记录,也有自己遇到的问题及解决方法,记下来方便自己查阅,也和大家一起学习ヽ(゚∀゚)メ(゚∀゚)ノ
我用的python版本:python-3.7.4
使用的IDE:PyCharm
再识Python
简介:
Python是荷兰人Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言(TAT)。89年出现第一个版本,比java早诞生,但是没火,因为是脚本语言,解释执行,运行慢。它的优点是代码量极少,算法入库,跨平台,多用于解决算法问题,是面向对象解释型的编程语言,定位是“优雅”、“明确”、“简单”。
ps:AWS亚马逊云服务是最顶尖的云服务。py可以在云服务器上运行,在硬件上弥补运行慢的问题。
其他缺点:
GIL(Global Interpreter Lock)全局解释器锁,这是一种防止多线程并发执行机器码的互斥锁,造成的后果就是Python在进行多线程任务的时候,其实是伪多线程,性能较差。
Python2和Python3的不兼容性。
应用场景:
web应用开发
服务器运维自动化脚本
科学计算、机器学习
云计算产品
Python命令行执行:
执行python hello.py运行一个.py文件,在命令行模式运行.py文件和在Python交互式环境下直接运行Python代码有所不同。Python交互式环境会把每一行Python代码的结果自动打印出来,但是直接运行Python代码却不会。
几种命令:
(终端运行)pip:python开源模块管理工具
(py命令行运行)import this:作者彩蛋(这个有意思)
基本语法:
缩进必为4个空格
大小写敏感
#为注释符号
输入输出:name = input(“请输入一个数字:”);print(name)
py3:已经将源文件默认编码定为utf-8 py2:# -*- coding: utf-8 -*
33个关键字:[‘False’, ‘None’, ‘True’, ‘and’, ‘as’, ‘assert’, ‘break’, ‘class’, ‘continue’, ‘def’, ‘del’, ‘elif’, ‘else’, ‘except’, ‘finally’, ‘for’, ‘from’, ‘global’, ‘if’, ‘import’, ‘in’, ‘is’, ‘lambda’, ‘nonlocal’, ‘not’, ‘or’, ‘pass’, ‘raise’, ‘return’, ‘try’, ‘while’, ‘with’, ‘yield’]
查看方法:
>>> import keyword
>>> keyword.kwlist
强类型定义语言:print(1+“2”)会编译出错,类型之间不会自动转换 int()/str() 动态语言:变量不用声明直接赋值
py原则上没有常量
基本数据类型:Number String List列表 Tuple元组 Sets集合 Dictionary字典
重要函数:使用type() 返回变量的类型,使用id() 返回对象的内存地址
相等的判断:==判断值;is判断内存地址;is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值 是否相等
数值类型:整型(int / long)、浮点型(float)、复数(complex)、布尔型(bool)
空值:Python里一个特殊的值,用None表示
整型字面值的表示方法有3种:十进制(常用)、 二进制(以数字“0b”开头)、八进制(以数字“0o”开头)和十六进制(以“0x”
或“0X”开头)
布尔型:其实是整型的子类型,布尔型数据只有两个取值:True和False,分别对应整型的1和0。布尔值可以用and、or和not运算。None/0/’’/[]/()/{}许多都可以转化为布尔类型。
不换行输出:print(‘123123’, end=’’)
注意:Python中没有++,–运算符,a+=1即可
在Python中没有switch – case语句
生成随机数:import random;n = random.randint(1,10)#在【1,10】范围内生成随机数
注意:range()函数不包括上限的值,直接写range(5)为从0开始
容器:包含其他对象的任意对象。序列(列表、元祖、字符串)、映射(字 典)、集合三类主要的容器。
序列:Python的切片总是左开右闭,从数学的可以理解为[index,index),切片可以接受三个参数, [start: end:
step]
-Python为序列内置了长度len()、最小值min()、最大值max()函数,字符串也可以用
列表:允许重复元素存在。
增加:append(n),insert(1,n)
删除:remove(n),pop()
修改、查找:利用下标进行修改
元组:初始化之后不允许修改,可以正常使用下标,转化为元组用tuple()
字符串:
多行字符串:使用三引号(’’'或""")可以指定一个多行字符串。
原生字符串:通过在字符串前加r或R,如 r"this is a line with \n",表示这个字符串里的斜杠不需要转义
截取字符串:Python 访问子字符串,可以使用方括号来截取字符串,print ("var2[1:5]: ", var2[1:5])
拼接字符串:print (“Name:%10s Age:%8d Height:%8.2f”%(“Aviad”,25,1.83));(更多采用:)print(‘asdasda {1},{0}’.format(‘a’,‘b’))
删除空格:strip()、lstrip()、rstrip()
按特定字符拆分:split(),查找py的正则表达式用法
字典:使用键-值(key-value)存储,具有极快的查找速度。
从Python3.6开始,字典是有序的!它将保持元素插入时的先后顺序。
多次对一个key放入value,后面的值会把前面的值覆盖掉
如果key不存在,dict就会报错,要避免key不存在的错误,可以通过in来判断或者通过dict提供的get()方法,如果key不存在,可以返回None,或者自己 指定的value
模块与函数:函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
递归少写,维护性差
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。
模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用python标准库的方法。使用import导入,或者from import
类属性只能通过类名.属性的方式修改
类中的私有变量/方法名 ,只有类对象自己能访问,子类对象 不能访问,与java不同
连接数据库:
mysql中编码upf8mb4可以存储emoji图像(安装时就设置好编码,以防后续出现问题)
ps:大部分网站为https,加密是通过协议进行,协议需要颁发(花钱),国内暂无颁发机构
请求信息会存入服务器日志。请求头必须设置,伪装自己像某个浏览器。
Python爬虫
主要步骤:
1、获取网页:获取网页的源代码,Python提供了许多库来帮助我们实现这个操作,如urllib、requests等。我们可以用这些库来帮助我们实现HTTP请求操作,请求和响应都可以用类库提供的数据结构来表示,得到响应之后只需要解析数据结构中的Body部分即可,即得到网页的源代码,这样我们可以用程序来实现获取网页的过程了。
2、提取信息:分析网页源代码,从中提取我们想要的数据。由于网页的结构有一定的规则,所以还有一些根据网页节点属性、CSS选择器或XPath来提取网页信息的库,如Beautiful Soup、pyquery、lxml等。使用这些库,我们可以高效快速地从中提取网页信息,如节点的属性、文本值等。
3、保存数据:保存形式有多种多样,如可以简单保存为TXT文本或JSON文本,也可以保存到数据库,如MySQL和MongoDB等。
ps:gb2312是gbk的子集
ps:403 Forbidden 您的IP访问频率太高:网站采取了一些反爬虫措施
服务器会检测某个IP在单位时间内的请求次数,如果超过了这个阈值,就会直接拒绝服务,返回一些错误信息,这种情况可以称为封IP。 措施:用代理服务器(高度匿名代理)(最强大的是BPN),或者手机上网(IP池)
ps:robot.txt约定哪些网站可以爬哪些不可以爬,但实质上是道德规范哈哈哈
第一种爬虫:urllib基本库+Beautiful Soup
urllib
urllib包含4个模块:
request(它是最基本的HTTP请求模块,可以用来模拟发送请求)error(异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止)parse(一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等)robotparser(主要是用来识别网站的robots.txt文件,然后判断哪些网站 可以爬,哪些网站不可以爬,它其实用得比较少)
这里附上官方文档:/3/library/urllib.html
Beautiful Soup
Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。Beautiful Soup会帮你节省数小时甚至数天的工作时间。
Beautiful Soup提供一些简单的、Python式的函数来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据, 因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为UTF-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时你仅 仅需要说明一下原始编码方式就可以了。
安装:
pip3 install beautifulsoup4
解析器:
这里我们单独安装lxml的解析器:
pip install lxml
使用:
from bs4 import BeautifulSoupsoup = BeautifulSoup(html_doc, 'html.parser') #html.parser为解析器选择print(soup.prettify())#格式化
这里给出4.4版本的文档:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/#id8
完整代码:
ps:使用的数据库为mysql 5.5
import urllib.requestfrom bs4 import BeautifulSoupimport pymysqlconfig = {'host':'localhost','user':'root','password':'123456', #这里写自己的数据库密码'database':'db', #这里写自己的数据库名称'charset':'utf8'}conn = pymysql.connect(**config)sql = 'insert into news(title,date) values(%s,%s)'#这里写自己的sql语句c = conn.cursor()#返回网页信息response = urllib.request.urlopen("http://115.**.**.**/*******")#这里写想要爬取的网页#输出测试# print(response.read().decode("utf-8"))print('访问状态:'+str(response.status))# print(response.getheaders)#解析#正则表达式:麻烦#beautiful soupsoup = BeautifulSoup(response.read().decode("utf-8"),'lxml')#注意编码与网页一致# print(soup.title)# print(soup.title.string)# print(soup.select("p[class='tit f-toe']")) #通过属性class查找# list = soup.select("p[class='tit f-toe'],.date") #可返回列表list = soup.select('div[class="col-xs-12 col-md-6 item nobrd"]')for n in list:title = n.select('p[class="tit f-toe"]')[0].string.strip()date = n.select('p[class="date"]')[0].string.strip()row = c.execute(sql, (title, date))#执行sql语句print(title,date)#打印观察mit()#别忘了提交!!!!
第二种爬虫:Scrapy+xpath
Scrapy
Scrapy是用python写的一个爬虫框架,当然如果只是写一些简单爬虫, python自己就有做爬虫的库,scrapy只是更加流水线化,各部分分工更加清晰。
优点:可以同时爬取多个网址,并行操作性能优越(调度器);主线程爬取内容,写文件、写数据库与爬取过程无关,存储过程出错不会影响爬取过程,相当于主线程与子线程的关系。
主要组件:
引擎控制器(Scrapy):用来处理整个系统的数据流, 触发事务(框架核心)
调度器(Scheduler):用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回.
可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它 来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader):用于下载网页内容,
并将网页内容返回给爬虫(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders):用于从特定的网页中提取自己需要的信息,
即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline):读写存储,负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
安装:
安装时可选择在线安装(pip install scrapy)及本地安装(pip install Twisted-18.4.0-cp36-cp36m-win_amd64.whl)
ps:在python3.6以上版本安装scrapy框架是会报错缺少Microsoft Visual C++ Build Tools,需要首先手动安装twisted, http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
pip install Twisted-18.4.0-cp36-cp36m-win_amd64.whl
• 在线安装Scrapy
pip install scrapy
• 安装支持模块
pip install pypiwin32
ps:创建项目靠terminal窗口
创建工程:
scrapy startproject scrapytest
spider.py:
allowed_domains = ['115.**.**.**'] #限制爬虫爬取范围,为域名列表,可同时爬取多个start_urls = ['http://115.**.**.**/*****] #开始爬取的网站,也可以为多个
执行:
使用命令来执行,或者写一个main:scrapy.cmdline.execute(argv=[‘scrapy’, ‘crawl’, ‘spider’, ‘–nolog’])
ps:打印的结果中红色信息为log日志信息(开头结尾都有),’–nolog’用于屏蔽log内容
xpath
解析使用xpath->查找DOM文档对象模型:树状结构
使用举例:
/html/head/title: 选择HTML文档中 标签内的
相关方法:
xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表。css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表。extract(): 序列化该节点为unicode字符串并返回list。re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。
这里有个坑:在循环中的当前节点查找时,不应使用//开头,这样会在根的范围下查找,应该首先在当前节点(.)查找,再根据相应情况查找所有符合条件的p节点
for r in rows:title = r.xpath('.//p[@class="tit f-toe"]/text()').extract_first().strip()
输出数据:
在settings文件中增加: FEED_EXPORT_ENCODING = 'utf-8’
在控制台写入scrapy crawl yourspidername -o data.json 仅用于调试代码
当Item在Spider中被收集之后,它将会被传递到pipeline,一些组件会按照一定的顺序执行对Item的处理。pipeline相关文档:/en/latest/topics/item-pipeline.html
分页问题:在前一页找到下一页
ExampleSpider.page += 1#默认第一页if response.xpath('//a[@href="/******?nowPage={}"]'.format(ExampleSpider.page)):nextpage = 'http://115.**.**.**/******?nowPage={}'.format(ExampleSpider.page)yield scrapy.Request(nextpage, callback=self.parse) #callback(回调函数)指向解析的下一个函数的指针
简易词云
import collectionsfrom PIL import Imageimport numpy as npimport matplotlib.pyplot as pltimport jieba #分词用from wordcloud import WordCloud, STOPWORDSpath_txt = 'E:/data.txt'#从文件中读file = open(path_txt, encoding="utf-8").read()#进行分词default_mode =jieba.cut(file)text = " ".join(default_mode)#自定义去除词库remove_words = [u'的', u',',u'和', u'并', u'前端', u'web', u'开发',u'熟悉',u'了解',u'都',u'。',u'',u'、',u';',u'.',u'中',u'在',u'了',u'需要',u'掌握',u'1',u'2',u'3',u'4',u'5',u'6',u'-',u'/',u'有',u'等',u'对',u'及',u'年',u';',u'(',u')',u',',u'(',u')',u':',u'\n',u'\xa0',u'能',u'或',u'者'] # 词频统计object_list = []for word in text.split(' '):if word not in remove_words:object_list.append(word)word_counts = collections.Counter(object_list) # 对分词做词频统计word_counts_top50 = word_counts.most_common(50) # 获取前50最高频的词print (word_counts_top50) #输出检查#存入数据库# conn = pymysql.connect(**config)# c = conn.cursor()# sql = 'insert into wordcloud(word,value) values(%s,%s)'# for i in word_counts_top50:#c.execute(sql, (i[0],str(i[1])))# mit()# conn.close()alice_mask = np.array(Image.open( r"E:/3.png"))print('加载图片成功!')wc = WordCloud(#设置字体,不指定就会出现乱码,这个字体文件需要下载font_path=r'E:/wqy-microhei.ttc',background_color="white",max_words=2000,mask=alice_mask,stopwords=remove_words)# 生成词云wc.generate(text)print('开始加载文本!')# 存入文件wc.to_file(r"E:/result.jpg")print('生成词云成功!')# 展示plt.imshow(wc, interpolation='bilinear')plt.axis("off")plt.show()
如果觉得《Python爬虫+简易词云的制作》对你有帮助,请点赞、收藏,并留下你的观点哦!