一、爬虫前准备
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 importrequests5 from fake_useragent importUserAgent6 importre7
8
9 defcreate_pool(ur):10 url =ur11
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('
(.*)', r.text)19 #正则匹配所有端口20 port = re.findall('
(.*)', r.text)2122 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 importrandom2 importrequests3 from fake_useragent importUserAgent4 importjson5 importre6 from bs4 importBeautifulSoup7 import matplotlib.pyplot as plt #用于图像处理
8 from wordcloud import WordCloud#用于生成词云
9 importnumpy as np10 from PIL importImage11
12 #词云形状文件 需要替换成你本地的图片
13 backgroud_Image = np.array(Image.open("man.jpg"))14 #词云字体 需要替换成你本地的字体
15 WC_FONT_PATH = '黄引齐招牌体.ttf'
16
17
18 defget_ip():19 f = open("ip-port.text", 'r') #从IP-port中读取IP
20 ip_all =[]21 for k inf: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 returnpr30
31
32 defget_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.random41 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_encoding75 #获取想要地址对应的BeautifulSoup
76 html = BeautifulSoup(respon.text, 'lxml')77 #选择 第六个script标签 即数据所在标签
78 try:79 src = html.select('script')[6].string80 #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 defcut_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 returnwl114
115
116 defcreate_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()
爬虫