爬虫之使用requests爬取某条标签并生成词云

一、爬虫前准备

1.工具:pychram(python3.7)

2.库:random,requests,fake-useragent,json,re,bs4,matplotlib,worldcloud,numpy,PIL,jieba

random:生成随机数

requests:发送请求获取网页信息

fake-useragent:生成代理服务器

json:数据转换

re:用于正则匹配

bs4:数据过滤

matpotlib:图像处理

worldcloud:生成词云

numpy:图像处理

PIL:图像处理

jieba:对中文进行分词(本次未用到)

3.爬虫流程

使用代码模拟浏览器发送请求-->浏览器返回信息(html/json)-->提取有用的信息-->进行储存

1)发起请求

使用代码向目标站点发送请求,即发送一个Request

请求应包含:请求头、请求体等 

2)获取响应内容

发送请求成功后,会获得站点返回的信息(Response)

3)提取信息

解析html数据:正则表达式(RE模块),第三方解析库如Beautifulsoup,pyquery,xpath等

解析json数据:json模块

4)储存信息

以文件存储

存入数据库

二、开始爬虫

1.防止ip被封

为了防止多次访问某站点导致IP被封,对IP进行伪装。

找一些提供免费IP的网站爬取IP数据存储到本地文件中,将爬虫进行到底。

 1 # __Author__ :"Chen Yang"
 2 # __Time__: 2019/8/22 20:56
 3 
 4 import requests
 5 from fake_useragent import UserAgent
 6 import re
 7 
 8 
 9 def create_pool(ur):
10     url = ur
11 
12     ua = UserAgent()
13     # fake_useragent 提供的随机生成代理服务器
14     headers = {"User-Agent": ua.random}
15 
16     r = requests.get(url, headers=headers)
17     # 正则匹配所有IP
18     comment = re.findall('<td data-title="IP">(.*)</td>', r.text)
19     # 正则匹配所有端口
20     port = re.findall('<td data-title="PORT">(.*)</td>', r.text)
21 
22     print(r.text)
23     print(comment)
24     print(port)
25     # 将IP和端口对应 存入文件
26     with open('ip-port.text', 'a', encoding='utf-8') as f:
27         for i in range(len(comment) - 1):
28             f.write(comment[i] + ":" + port[i])
29             f.write('\n')
30 
31 
32 if __name__ == "__main__":
33     # 爬取该网页前7页IP
34     for i in range(6):
35         ur = 'http://www.qydaili.com/free/?action=china&page=' + str(i)
36         create_pool(ur)
IP爬取

 

2.IP爬取成功后正式开始爬取某条

xhr:XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。

某条文章是动态随机推荐的,每次进入头条页面的文章都不同。

在多次分析后找到realtime_news/的xhr

访问open_url,爬取标签

至此,基本可以确定realtime_news的xhr就是要爬的文件。

思路:爬取realtime_news的xhr的文件-->获取其中open_url-->爬取标签-->生成词云

  1 import random
  2 import requests
  3 from fake_useragent import UserAgent
  4 import json
  5 import re
  6 from bs4 import BeautifulSoup
  7 import matplotlib.pyplot as plt  # 用于图像处理
  8 from wordcloud import WordCloud# 用于生成词云
  9 import numpy as np
 10 from PIL import Image
 11 
 12 # 词云形状文件  需要替换成你本地的图片
 13 backgroud_Image = np.array(Image.open("man.jpg"))
 14 # 词云字体 需要替换成你本地的字体
 15 WC_FONT_PATH = '黄引齐招牌体.ttf'
 16 
 17 
 18 def get_ip():
 19     f = open("ip-port.text", 'r')  # 从IP-port中读取IP
 20     ip_all = []
 21     for k in f:
 22         line = f.readline()
 23         ip_all.append(line[:-1])  # 去除/n
 24     f.close()
 25     # print(ip_all)
 26     i = random.randint(0, len(ip_all)-1)
 27     pr = ip_all[i]
 28     print("ip地址为:{}".format(pr))
 29     return pr
 30 
 31 
 32 def get_info():
 33     '''
 34     使用爬取的ip来进行ip代理
 35     使用fake_useragent进行服务器代理,防止IP被封
 36     '''
 37     url = 'https://www.toutiao.com/api/pc/realtime_news/'
 38 
 39     ua = UserAgent()
 40     agent = ua.random
 41     print("代理为:{}".format(agent))
 42     header = {"User-Agent": agent}
 43 
 44     ip = get_ip()
 45     proxies = {'url': ip}
 46 
 47     try:
 48         # 获取首页信息
 49         r = requests.get(url, headers=header, proxies=proxies)
 50         global_json = json.loads(r.text)
 51         print(global_json)
 52     except:
 53         print("请求头条主页失败")
 54 
 55     # 获取首页信息动态推荐文章的地址
 56     article = []
 57     for i in range(len(global_json['data'])):
 58         article.append(global_json['data'][i]['open_url'])
 59     # 头条得子文章页标号 会随机发生变化
 60     #print(article)
 61 
 62     # 取8篇文章得label
 63     for i in range(7):
 64         # 访问动态推荐文章地址
 65         content = "http://toutiao.com" + article[i]
 66         try:
 67             respon = requests.get(content, headers=header, proxies=proxies)
 68             # 输入返回对象的文本值
 69             # print(respon.text)
 70         except:
 71             print("请求文章失败")
 72 
 73         # 指定编码等于原始页面编码
 74         respon.encoding = respon.apparent_encoding
 75         # 获取想要地址对应的BeautifulSoup
 76         html = BeautifulSoup(respon.text, 'lxml')
 77         # 选择 第六个script标签 即数据所在标签
 78         try:
 79             src = html.select('script')[6].string
 80             #print(src)
 81         except:
 82             print("获取数据失败!")
 83         result = []
 84         try:
 85             # 正则找到数据中标签字段
 86             labels = re.findall('tags:(.*),', respon.text)
 87             #print(type(labels))
 88             # strip()去空格
 89             # 把字符串转为列表
 90             result = labels[0].strip()
 91             # print(type(result))
 92             # print(labels)
 93             # eval()  将字符串列表 转为列表
 94             result = eval(result)
 95             # print(result)
 96         except:
 97             print("未获得labels")
 98         with open("labels.json", 'a', encoding='utf-8') as f:
 99             for i in range(len(result)-1):
100                 f.write(result[i]['name'])
101                 f.write(' ')
102 
103 
104 def cut_word():
105     '''
106     生成词云
107     :return:
108     '''
109     with open("labels.json", 'r', encoding='utf-8') as f:
110         label =f.read()
111         wl = "".join(label)
112         print(wl)
113         return wl
114 
115 
116 def create_word_cloud():
117     '''
118     生成词云
119     :return:
120     '''
121     # 设置词云形状图片
122     #wc_mask = np.array(WC_MASK_IMG)
123     # 设置词云配置 字体 背景 大小等
124     wc = WordCloud(background_color='white', max_words=2000, mask=backgroud_Image, scale=4,
125                    max_font_size=50, random_state=42, font_path=WC_FONT_PATH)
126     # 生成词云
127     wc.generate(cut_word())
128 
129     # 在只设置mask情况下, 你会得到一个图片形得词云
130     plt.imshow(wc, interpolation='bilinear')
131     #plt.axis("off")
132     plt.figure()
133     plt.show()
134 
135 
136 if __name__ == '__main__':
137     get_info()
138     create_word_cloud()
爬虫

 

posted @ 2019-08-27 10:20  耳东三羊  阅读(1562)  评论(0编辑  收藏  举报