0


保姆级爬虫零基础一条龙式教程(超详细)

一、准备工作:

1、网页分析:

进入目标网页,按下键盘F12,必须要认识图中画圈的部分。

箭头:

这个小箭头非常实用,点击后,在正常网页中点击哪个部分,代码区高光就会找到相应的代码。

Element:

包含网页源码,很多数据都从这里获得。

NetWork:

网络工作记录,按下图顺序点击,会得到很多响应信息。比如:请求头(Header)信息、Cookie、User-Agent等等,作用下面说。

2、环境配置:

** 需要提前下载好,这部分下载去网上搜就行,这里不做过多描述。**

python包安装:

bs4->BeautifulSoup(用于网页解析,获取数据)

re->正则表达式进行文字匹配

urllib.request,urllib.error->指定URL获取网页数据

xlwt->进行Excel操作

sqlite3->进行数据库操作#本教程面向编程零基础不会涉及数据库操作,这个可以不下

(后面还会用到一些其他的,看到再说)

二、构建流程:

四个模块:获取-解析-保存-可视化。后面都会写相应的函数。

1、获取网页数据

  1. 首先获取网页数据,想要获取网页数据,就要向目标网页发出请求,请求的方式有很多种,python爬虫最常用的有两种**Get**和**Post**,这里主要介绍一下这两种请求怎么使用。
  2. 这是我们测试请求方式的网站:

httpbin.orghttp://httpbin.org/

打开点击HTTP Methods:

选择一种测试方式:

首先我们来做一个Get请求:

  1. import urllib.request as ur
  2. res = ur.urlopen("http://httpbin.org/get")
  3. print(res.read().decode('utf-8'))

非常简单使用的请求方式,平时只要加入一个请求头就可以了,不需要数据包等参数。

我们再来看一下Post请求怎么做:

  1. post请求需要我们封装好一个字典形式的数据包并解码成二进制的格式传递给要访问的网页,同时在网址后面要有 /post 标识,然后将数据包传入,代码如下:
  1. import urllib.request as ur
  2. import urllib.parse as up
  3. data = bytes(up.urlencode({"hello":"world"}),encoding="utf-8")#字典封装数据包解码成2进制
  4. res = ur.urlopen("http://httpbin.org/post",data=data)#使用post请求
  5. print(res.read().decode('utf-8'))

那么,这种请求发出去都包含什么信息呢?我们来运行上述代码来看一下:

上图就是网站接收到的你发出的请求,也就是你的数据信息。非常尴尬的是,你的代理直接写的就是python-urllib,这无疑就是在对你访问的网页进行挑衅,“我就是爬虫,我就是来爬你的!”这样做无疑是非常愚蠢的,一般包容性强的网站可不会理会你,但是如果遇到强势一点的网站,那么迎接你的肯定就是:418或者403。

所以我们通常要对爬虫进行伪装,也就是用浏览器的身份去爬取信息而不是python。稍后我们会讲如何伪装,先别急,先看看其他操作。

超时处理:

  1. import urllib.request as ur
  2. res = ur.urlopen("http://httpbin.org/get",timeout=0.01)
  3. print(res.read().decode('utf-8'))

如果响应时间超过timeout就代表程序没有响应,这时会报错。然后我们进行超时处理。

*这里timeOut设置成0.01是为了测试超时效果

  1. import urllib.request as ur
  2. import urllib.error
  3. try:
  4. res = ur.urlopen("http://httpbin.org/get",timeout=0.01)
  5. print(res.read().decode('utf-8'))
  6. except urllib.error.URLError as e:
  7. print("Time Out!")

查看状态码:

  1. import urllib.request as ur
  2. import urllib.error
  3. res = ur.urlopen("http://douban.com")
  4. print(res.status)

提示418,证明你的爬虫身份暴露了。

输出网页头:

  1. import urllib.request as ur
  2. import urllib.error
  3. res = ur.urlopen("http://baidu.com")
  4. print(res.getheaders())

比对一下:

无差别。

上面这些示例主要想说明:requset的功能是十分强大的,它所获取的信息是你能在网页上找到的所有信息。

获取部分信息:

  1. import urllib.request as ur
  2. import urllib.error
  3. res = ur.urlopen("http://www.baidu.com")
  4. #print(res.getheaders());
  5. print(res.getheader("Set-Cookie"))

由此可见Request函数貌似可以访问网页上的所有信息这样我们也就可以获取网页代理的信息,通过这个代理就可以对爬虫进行伪装,防止被网站发现了。

伪装爬虫——模拟网页代理:

首先,找到我们浏览器的代理信息:

  1. F12 -- NetWork -- Header -- User-Agent

1、复制粘贴到代码中封装成键值对。

  1. 如果封装一个代理还是会被发现是爬虫,那就多封装几个信息加强对网站的迷惑性。

通常还会使用:Remote Address等等。

  1. headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}

2、设置请求方式:(get可以不用写/get)

  1. req = ur.Request(url = url,data=data,headers = headers,method="POST")

3、读取网页源码:

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. url = "http://httpbin.org/post"
  5. headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}
  6. data = bytes(up.urlencode({'name':'eric'}),encoding='utf-8')
  7. req = ur.Request(url = url,data=data,headers = headers,method="POST")
  8. res = ur.urlopen(req)
  9. print(res.read().decode("utf-8"))

输出结果:

妈妈再也不用担心我的爬虫被发现啦!

下面再用get请求的方式访问一下刚刚被发现的网站:

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. url = "https://douban.com"
  5. headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}
  6. req = ur.Request(url = url,headers = headers)
  7. res = ur.urlopen(req)
  8. print(res.read().decode("utf-8"))

成功打入对方内部,是获取信息的第一步。

下面进行获取数据:

示例网址:豆瓣电影 Top 250

(1)得到一个指定页面信息

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. #得到一个指定的URL内容
  5. def askURL(url):
  6. #模拟请求头
  7. header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}
  8. #保存网页信息的字符串
  9. html=""
  10. #请求网页信息
  11. req = ur.Request(url,headers=header)
  12. try:
  13. res = ur.urlopen(req)
  14. html=res.read().decode("utf-8")
  15. print(html)
  16. except ue.URLError as e:
  17. if hasattr(e,"code"):
  18. print(e.code)
  19. if hasattr(e,"reason"):
  20. print(e.reason)
  21. if __name__ == "__main__":
  22. url = "https://movie.douban.com/top250?end=249&filter="
  23. askURL(url)
  24. print(1)

用循环获取多个页面信息:

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. #得到一个指定的URL内容
  5. def askURL(url):
  6. #模拟请求头
  7. header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}
  8. #保存网页信息的字符串
  9. html=""
  10. #请求网页信息
  11. req = ur.Request(url,headers=header)
  12. try:
  13. res = ur.urlopen(req)
  14. html=res.read().decode("utf-8")
  15. print(html)
  16. except ue.URLError as e:
  17. if hasattr(e,"code"):
  18. print(e.code)
  19. if hasattr(e,"reason"):
  20. print(e.reason)
  21. return html
  22. #爬取网页
  23. def getData(url):
  24. dataList = []
  25. for i in range(0,10):#调用获取页面信息函数10250
  26. url = url+str(i*25)#左闭右开
  27. html = askURL(url)#保存获取到的网页源码
  28. #逐一解析
  29. if __name__ == "__main__":
  30. url = "https://movie.douban.com/top250?start="
  31. #1、爬取网页
  32. dataList = getData(url)
  33. savepath = ".\\豆瓣电影Top250.xls"

2、解析网页数据

解析网页数据常用的库就是BeautifulSoup

示例:百度一下,你就知道

(1)、获取网页Tag(标签):

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.title)
  6. print(html.a)
  7. print(type(html.title))
  8. print(type(html.a))
  9. print("标签及其内容:默认是第一个找到的")

输出:

(2)获取NavigableString(标签里的内容):

以字符串形式:

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.title)
  6. print(html.title.string)

输出:

获取标签的内容以字典形式:

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.a)
  6. print(html.a.attrs)

输出:

(3) 获取BeautifulSoup(整个网易文档):

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html)
  6. print(type(html))

输出:

(4)获取Comment(注释:特殊的NavigableString输出内容不包含字符串):

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.a.string)

输出:

(5)遍历BeautifulSoup:

  1. 我们什么时候用遍历这个词?通常是用在一组可连续查找的数据结构中对吧,比如列表、树等等。在我们的beautifulsoup中获取的内容也都是存在列表中的,如下:
  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.body.contents)

输出:

既然是列表,那么我们就可以用下标来找其中的某一个固定元素:

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. print(html.body.contents[0])

除了content以外,还有更多的获取子节点的方法:

BeautifulSoup——搜索

  1. 上面讲的是一种遍历方法,把获取的文件内容(结点)放在容器(生成器)中然后遍历找到某一个想要获取的信息(元素)。

接下来介绍一种更加实用且便捷的方式,通过搜索来到自己想要的内容。

(1)find_all()

  1. 字符串过滤:会找到与字符串完全匹配的内容。
  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. url = ur.urlopen("https://baidu.com")
  4. html = BeautifulSoup(url,'html.parser')
  5. t_list = html.find_all("a")
  6. print(t_list)

(2)正则表达式搜索:使用search()方法来匹配内容

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. url = ur.urlopen("https://baidu.com")
  5. html = BeautifulSoup(url,'html.parser')
  6. t_list = html.find_all(re.compile("a"))
  7. print(t_list)

这次输出的内容明显和上次的不同,因为在使用正则表达式时要按照符合正则表达式的内容进行查找,而不是单独去找一个带“a”的字符串。

但是相同点是,查找的范围都是标签,字符串查找“a”是找Tag就是a的标签

正则表达式查找“a”是找Tag中带有a的标签。

(3)方法:传入一个函数,根据函数来搜索。

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(name_is_exists)
  9. print(t_list)

查找所有带有name的标签。

(4)kwargs(参数)搜索

查找标签中带有id=head的字段。

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(id = "head")
  9. print(t_list)

查找一段带有这个超链接的字段。

  1. mport urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(href = "http://news.baidu.com")
  9. print(t_list)

(5)text 文本参数

  1. 获取文本内容
  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(text = "hao123" )
  9. for i in t_list:
  10. print(i)

还可以用列表去查找文本

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(text = ["hao123","新闻","视频"] )
  9. for i in t_list:
  10. print(i)

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all(text = re.compile("\d") )#用正则表达查找带有特定内容的文本字符串
  9. for i in t_list:
  10. print(i)

(6)limit 参数

限定查找个数。

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.find_all("a",limit=3)
  9. for i in t_list:
  10. print(i)

(7)css选择器

通过标签查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("title")
  9. for i in t_list:
  10. print(i)

(8)通过类名查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select(".mnav")
  9. for i in t_list:
  10. print(i)

(9)通过id查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("#u1")
  9. for i in t_list:
  10. print(i)

(10) 通过属性查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("a[class = 'text-color']")
  9. for i in t_list:
  10. print(i)

(11) 通过子标签查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("div>div")
  9. for i in t_list:
  10. print(i)

(12)通过兄弟标签查找

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("div~div")
  9. for i in t_list:
  10. print(i)

(13)通过下标查找文本

  1. import urllib.request as ur
  2. from bs4 import BeautifulSoup
  3. import re
  4. def name_is_exists(tag):
  5. return tag.has_attr("name")
  6. url = ur.urlopen("https://baidu.com")
  7. html = BeautifulSoup(url,'html.parser')
  8. t_list = html.select("div~div")
  9. print(t_list[1].get_text())

正则表达式——Re库

举个例子:

字符串的匹配测试:

  1. import re
  2. slist=["aaa","AA","ACA","AAA","CAB"]#等待校验的字符串列表
  3. bat = re.compile("AA")#定义正则表达式
  4. for i in slist:
  5. res = bat.search(i)#搜索与之匹配的字符串
  6. print(res)

上述匹配也可以简写:

  1. import re
  2. bat = re.compile("AA")#定义正则表达式
  3. m = re.search("AA","ABCAA");
  4. print(m)

findall()与正则表达式结合

  1. 将符合规则的字符存入列表。
  1. import re
  2. print(re.findall("[A-Z]","sdsaASDSAdfdsSasdSda"));

sub()函数(替换)

  1. import re
  2. print(re.sub("a","A","sdsaASDSAdfdsSasdSda"));#所有aA替换

建议在正则表达式中,被比较的对象前面加上 r 避免转义字符被误用

  1. a = r"\asdas\'"

正则提取

找到肖申克的救赎代码信息:

对内容进行正则提取:

  1. #创建正则表达式
  2. #影片链接
  3. findLink=re.compile(r'<a href="(.*?)">')#(.*?):.*:任意字符出现多次 ?:前面的元组内容出现仅出现一次
  4. #影片图片
  5. findImagSrc=re.compile(r'<img.*src="(.*?)"',re.S);#re.S:将换行符忽视掉
  6. #片名
  7. findTitle = re.compile(r'<span class="title">(.*)</span>')
  8. #评分
  9. findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  10. #评价人数
  11. findJudge = re.compile(r'<span>(\d)*人评价</span>')
  12. #找到概况
  13. findInq = re.compile(r'<span class="inq">(.*)</span>')
  14. #相关内容
  15. findBd = re.compile(r'<p class="">(.*)</p>',re.S)

标签解析

将爬取数据存入列表

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. from bs4 import BeautifulSoup
  5. import re
  6. #得到一个指定的URL内容
  7. def askURL(url):
  8. #模拟请求头
  9. header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44"}
  10. #保存网页信息的字符串
  11. html=""
  12. #请求网页信息
  13. req = ur.Request(url,headers=header)
  14. try:
  15. res = ur.urlopen(req)
  16. html=res.read().decode("utf-8")
  17. #print(html)
  18. except ue.URLError as e:
  19. if hasattr(e,"code"):
  20. print(e.code)
  21. if hasattr(e,"reason"):
  22. print(e.reason)
  23. return html
  24. #创建正则表达式
  25. #影片链接
  26. findLink=re.compile(r'<a href="(.*?)">')#(.*?):.*:任意字符出现多次 ?:前面的元组内容出现仅出现一次
  27. #影片图片
  28. findImagSrc=re.compile(r'<img.*src="(.*?)"',re.S);#re.S:将换行符忽视掉
  29. #片名
  30. findTitle = re.compile(r'<span class="title">(.*)</span>')
  31. #评分
  32. findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  33. #评价人数
  34. findJudge = re.compile(r'<span>(\d)*人评价</span>')
  35. #找到概况
  36. findInq = re.compile(r'<span class="inq">(.*)</span>')
  37. #相关内容
  38. findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
  39. #爬取网页
  40. def getData(url):
  41. dataList = []
  42. for i in range(0,1):#调用获取页面信息函数10250
  43. url = url+str(i*25)#左闭右开
  44. html = askURL(url)#保存获取到的网页源码
  45. #逐一解析
  46. soup = BeautifulSoup(html,"html.parser")
  47. for item in soup.find_all('div',class_="item"):#查找比较好的字符串放入列表
  48. #print(item) 测试:查看电影item全部信息
  49. data = [] #保存一部电影的所有信息
  50. item = str(item)
  51. #影片详情链接
  52. Link = re.findall(findLink,item)[0]#re库用来通过正则表达式查找指定字符串,0表示只要第一次找到的
  53. data.append(Link)
  54. ImgSrc = re.findall(findImagSrc,item)[0]
  55. data.append(ImgSrc)
  56. Title = re.findall(findTitle,item)#区分中英文
  57. if len(Title)==2:
  58. ctitle=Title[0]
  59. data.append(ctitle)
  60. otitle = Title[1].replace("/","")#去掉无关符号
  61. data.append(otitle)#添加外国名
  62. else:
  63. data.append(Title[0])
  64. data.append(' ')#表中留空
  65. Rating = re.findall(findRating,item)[0]
  66. data.append(Rating)
  67. Judge = re.findall(findJudge,item)[0]
  68. data.append(Judge)
  69. Inq = re.findall(findInq,item)
  70. if len(Inq)!=0:
  71. Inq=Inq[0].replace("。","")#去掉句号
  72. data.append(Inq)
  73. else:
  74. data.append(" ")#表留空
  75. Bd = re.findall(findBd,item)[0]
  76. Bd = re.sub('<br(\s+)?/>(\s+)?'," ",Bd)#去掉<br/>
  77. Bd = re.sub('/'," ",Bd)#去掉/
  78. data.append(Bd.strip())#去掉前后空格
  79. dataList.append(data)#把处理好的一部电影信息放入dataList
  80. print(dataList)
  81. return dataList
  82. if __name__ == "__main__":
  83. url = "https://movie.douban.com/top250?start="
  84. #1、爬取网页
  85. dataList = getData(url)
  86. savepath = ".\\豆瓣电影Top250.xls"

3、保存数据

保存数据到Excel

四步保存法:

创建表

创建子表

写入数据

保存数据

  1. import xlwt
  2. workbook = xlwt.Workbook(encoding="utf-8")#创建workbook对象
  3. worksheet = workbook.add_sheet('sheet1')#创建工作表
  4. worksheet.write(0,0,'hello')#00列存入内容hello
  5. workbook.save('student.xls')#保存数据

实例:用python在excel中打印九九乘法表:

  1. import xlwt
  2. workbook = xlwt.Workbook(encoding="utf-8")#创建workbook对象
  3. worksheet = workbook.add_sheet('sheet1')#创建工作表
  4. for k in range(1,10):
  5. for i in range(1,10):
  6. if i<=k:
  7. worksheet.write(k-1,i-1,str(i*k))#00列存入内容hello
  8. workbook.save('student.xls')#保存数据

完善之前的代码:

  1. import urllib.request as ur
  2. import urllib.error as ue
  3. import urllib.parse as up
  4. from bs4 import BeautifulSoup
  5. import re
  6. import xlwt
  7. #创建正则表达式
  8. #影片链接
  9. findLink=re.compile(r'<a href="(.*?)">')#(.*?):.*:任意字符出现多次 ?:前面的元组内容出现仅出现一次
  10. #影片图片
  11. findImagSrc=re.compile(r'<img.*src="(.*?)"',re.S);#re.S:将换行符忽视掉
  12. #片名
  13. findTitle = re.compile(r'<span class="title">(.*)</span>')
  14. #评分
  15. findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
  16. #评价人数
  17. findJudge = re.compile(r'<span>(\d*)人评价</span>')
  18. #找到概况
  19. findInq = re.compile(r'<span class="inq">(.*)</span>')
  20. #相关内容
  21. findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
  22. def main():
  23. baseurl = "https://movie.douban.com/top250?start="
  24. datalist = getData(baseurl)
  25. savepath = "douban.xls"
  26. saveData(datalist,savepath)
  27. #得到一个指定的URL内容
  28. def askURL(url):
  29. #模拟请求头
  30. header = {"Remote Address":"140.143.177.206:443","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"}
  31. #保存网页信息的字符串
  32. html=""
  33. #请求网页信息
  34. req = ur.Request(url,headers=header)
  35. try:
  36. res = ur.urlopen(req)
  37. html=res.read().decode("utf-8")
  38. #print(html)
  39. except ue.URLError as e:
  40. if hasattr(e,"code"):
  41. print(e.code)
  42. if hasattr(e,"reason"):
  43. print(e.reason)
  44. return html
  45. #爬取网页
  46. def getData(baseurl):
  47. dataList = []#用来存储网页信息
  48. for i in range(0,10):#调用获取页面信息函数10250
  49. url = baseurl+str(i*25)#左闭右开
  50. html = askURL(url)#保存获取到的网页源码
  51. #逐一解析
  52. soup = BeautifulSoup(html,"html.parser")
  53. for item in soup.find_all('div',class_="item"):#查找比较好的字符串放入列表
  54. #print(item) 测试:查看电影item全部信息
  55. data = [] #保存一部电影的所有信息
  56. item = str(item)
  57. #影片详情链接
  58. Link = re.findall(findLink,item)[0]#re库用来通过正则表达式查找指定字符串,0表示只要第一次找到的
  59. data.append(Link)
  60. ImagSrc = re.findall(findImagSrc,item)[0]
  61. data.append(ImagSrc)
  62. Title = re.findall(findTitle,item)#区分中英文
  63. if len(Title)==2:
  64. ctitle=Title[0]
  65. data.append(ctitle)
  66. otitle = Title[1].replace("/","")#去掉无关符号
  67. data.append(otitle)#添加外国名
  68. else:
  69. data.append(Title[0])
  70. data.append(' ')#表中留空
  71. Rating = re.findall(findRating,item)[0]
  72. data.append(Rating)
  73. Judge = re.findall(findJudge,item)[0]
  74. data.append(Judge)
  75. Inq = re.findall(findInq,item)
  76. if len(Inq)!=0:
  77. Inq=Inq[0].replace("。","")#去掉句号
  78. data.append(Inq)
  79. else:
  80. data.append(" ")#表留空
  81. Bd = re.findall(findBd,item)[0]
  82. Bd = re.sub('<br(\s+)?/>(\s+)?'," ",Bd)#去掉<br/>
  83. Bd = re.sub('/'," ",Bd)#去掉/
  84. data.append(Bd.strip())#去掉前后空格
  85. dataList.append(data)#把处理好的一部电影信息放入dataList
  86. return dataList
  87. def saveData(datalist,savepath):
  88. print("saving")
  89. book = xlwt.Workbook(encoding="utf-8",style_compression=0)#创建workbook对象
  90. sheet = book.add_sheet('豆瓣电影Top',cell_overwrite_ok=True)#创建工作表
  91. col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
  92. for i in range(0,8):
  93. sheet.write(0,i,col[i])#列名
  94. for i in range(0,250):
  95. print("第%d条"%i)
  96. data = datalist[i]
  97. for j in range(0,8):#数据
  98. sheet.write(i+1,j,data[j]) #保存
  99. book.save(savepath)#保存
  100. if __name__ == "__main__":
  101. main()
  102. print("爬取成功!")

符合预期效果。

4、数据可视化

制作词云:

掩图:

词图:

环境配置:

  1. import jieba#分词
  2. from matplotlib import pyplot as plt#绘图数据可视化
  3. from wordcloud import WordCloud#词云
  4. from PIL import Image#图像处理
  5. import numpy as np#矩阵运算
  6. import pandas as pd
  7. import re

示例:

  1. import jieba#分词
  2. from matplotlib import pyplot as plt#绘图数据可视化
  3. from wordcloud import WordCloud#词云
  4. from PIL import Image#图像处理
  5. import numpy as np#矩阵运算
  6. import pandas as pd
  7. import re
  8. data = pd.read_excel('douban.xls')#打开Excel文件
  9. data_cy = data.copy()#不影响原数据所以拷贝一份
  10. #print(data.iloc[0:4,:2])#从x开始到第y行的前x列
  11. #print(data.iloc[[0],[2,3]])#第0行的2、3列
  12. list=[]
  13. for i in range(0,250):
  14. datas = data.iloc[[i],[2]]#获取名字
  15. datas = str(datas).strip()
  16. datas = re.sub(r"影片中文名\n\d*","",datas)
  17. datas = str(datas).strip()#再去掉一次空格
  18. list.append(datas)
  19. #print(list)#得到影片名字的列表
  20. #获取所有文字
  21. text=""
  22. for item in list:
  23. text+=item
  24. #print(text)
  25. #分词
  26. cut = jieba.cut(text)
  27. string = " ".join(cut)
  28. print(string)#1220
  29. img = Image.open("kobe.jpg")
  30. img_=np.array(img)
  31. wc=WordCloud(
  32. mask=img_,
  33. background_color='white',
  34. font_path='msyh.ttc'
  35. )
  36. wc.generate_from_text(string)
  37. fig = plt.figure(1)
  38. plt.imshow(wc)
  39. plt.axis('off')
  40. plt.savefig("D:\代码文件夹\VS代码\PythonApplication30\PythonApplication30\wc.jpg")
标签: 爬虫

本文转载自: https://blog.csdn.net/qq_51701007/article/details/124301264
版权归原作者 代码骑士 所有, 如有侵权,请联系我们删除。

“保姆级爬虫零基础一条龙式教程(超详细)”的评论:

还没有评论