php 抓取 百度百科,百度百科词条内容爬取-爬虫大作业

实现过程

一、前期准备

首先打开要爬取的页面,作为根源页面。

我这里使用的百度百科的PHP词条,网址为https://baike.baidu.com/item/PHP/9337?fr=aladdin&fromid=6717846&fromtitle=%EF%BC%B0%EF%BC%A8%EF%BC%B0

然后选取其中适合收集信息的文字内容,右键审查。

2662dd6f3c756ca514fde94d833c145f.png

可以发现该词条内关联的词条(url)非常多

f9c34e5c9cdf9de6e0f0b141c924e434.gif

装好软件和相关第三方库,开搞♂。

环境如下:

python3.6.2    PyCharm

Windows10    第三方库(jieba,wordcloud,bs4,Requests,re)

二、写代码

爬虫的架构大致如下

6a1accdcd7785aca0adf71a3ef1fbc6d.png

第一步先写个main来做调度,列好要实现的功能。

def __init__(self):

self.urls=url_manager.UrlManager() #url管理器

self.downloader=html_downloader.HtmlDownloader()#下载器

self.parser=html_parser.HtmlParser()#解析

self.outputer=html_outputer.HtmlOutouter()#输出

然后写

def craw(self,root_url):

count=1

self.urls.add_new_url(root_url)

while self.urls.has_new_url():

try:

new_url=self.urls.get_new_url()

print('craw %d:%s'%(count,new_url))

html_cont=self.downloader.download(new_url)

new_urls,new_data=self.parser.parse(new_url,html_cont)

self.urls.add_new_urls(new_urls)

self.outputer.collest_data(new_data)

if count>500:

break

count+=1

except Exception as e:

print(str(e))

self.outputer.output_html()

if __name__=="__main__":

root_url='https://baike.baidu.com/item/PHP/9337?fr=aladdin&fromid=6717846&fromtitle=%EF%BC%B0%EF%BC%A8%EF%BC%B0'

obj_spider=SpiderMain()

obj_spider.craw(root_url)

url管理器

class UrlManager(object):

def __init__(self):

self.new_urls =set()

self.old_urls = set()

def add_new_url(self,url):

if url is None:

return

if url not in self.new_urls and url not in self.old_urls:

self.new_urls.add(url)

def add_new_urls(self,urls):

if urls is None or len(urls)==0:

return

for url in urls:

self.add_new_url(url)

def has_new_url(self):

return len(self.new_urls)!=0

def get_new_url(self):

new_url = self.new_urls.pop()

self.old_urls.add(new_url)

return new_url

接下来写下载器

class HtmlDownloader(object):

def download(self,url):

if url is None:

return None

url_ =quote(url,safe=string.printable)

response =request.urlopen(url_)

if response.getcode()!=200:

return None

return response.read()

解析器来一个,百度百科链接的规律是baike.baidu.com/item/*

from bs4 import BeautifulSoup

import re

import urllib.parse

class HtmlParser(object):

def _get_new_urls(self, page_url, soup):

new_urls = set()

links=soup.find_all('a',href=re.compile(r"/item/"))

for link in links:

new_url = link['href']

new_full_url=urllib.parse.urljoin(page_url,new_url)

new_urls.add(new_full_url)

return new_urls

def _get_new_data(self, page_url, soup):

res_data = {}

# url

res_data['url'] = page_url

title_node = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1')

res_data['title'] = title_node.get_text()

#

summary_node = soup.find('div', class_='lemma-summary')

if summary_node is None:

return

res_data['summary'] = summary_node.get_text()

#

para_node = soup.find('div', class_='para')

if para_node is None:

return

res_data['para'] = para_node.get_text()

return res_data

def parse(self,page_url,html_cont):

if page_url is None or html_cont is None:

return

soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')

new_urls=self._get_new_urls(page_url,soup)

new_data=self._get_new_data(page_url,soup)

return new_urls,new_data

输出到一个叫output.txt的文件

# -*- coding: UTF-8 -*-

class HtmlOutouter(object):

def __init__(self):

self.datas=[]

def collest_data(self, new_data):

if new_data is None:

return

self.datas.append(new_data)

def output_html(self):

fout=open('output.txt','w',encoding='utf-8')

for data in self.datas:

fout.write('%s' % ( data['title']))

fout.write('%s' % data['para'])

fout.write('%s' % data['summary'])

fout.close()

得到txt文件一个

44b728e6d4e02276312c8bd48ed96ab7.png

里面有爬了五百个url搞到手的文字内容。

f3bb63425eed5eedd818c2d657baafb4.png

三、生成词云

装词云库时有点小麻烦,下面再说。

#通过jieba分词进行分词并通过空格分隔

wordlist_after_jieba = jieba.cut(text_from_file_with_apath, cut_all = True)

wl_space_split = " ".join(wordlist_after_jieba)

#my_wordcloud = WordCloud().generate(wl_space_split) 默认构造函数

my_wordcloud = WordCloud(

background_color='white', # 设置背景颜色

mask = abel_mask, # 设置背景图片

max_words = 800, # 设置最大现实的字数

stopwords = {}.fromkeys(['以及', '就是','可以','简称','位于','称为','之一','包括','一种','主要']), # 设置停用词

font_path = 'C:/Users/Windows/fonts/simkai.ttf',# 设置字体格式,如不设置显示不了中文

max_font_size = 50, # 设置字体最大值

random_state = 30, # 设置有多少种随机生成状态,即有多少种配色方案

scale=.5

).generate(wl_space_split)

# 根据图片生成词云颜色

image_colors = ImageColorGenerator(abel_mask)

调用,运行

背景图为

22527b0c1aaa6c4d5e251b1c284dece5.png

生成的词云图为

004b153c3691c7767649831bd40ef39f.png

完成

遇到的问题及解决办法

1.word cloud安装失败,根据错误报告提示缺少vs c++构建工具。通过安装一个vs2017解决。

2.一开始是打算爬百度贴吧的,但是爬百度贴吧的时候IP被拉黑了。本来打算通过动态IP的方式,但是没成功。所以去爬百度百科了。

3.词云生成的图片过于模糊,文字看不清楚。多次尝试发现跟原图的分辨率有关,换张分辨率高的图片获得不错的效果。

4.词云中无意义的词(如连接词等)太多。没搞到常用stopwords文件(csdn要三个积分),只能手动加了几个无意义的过滤词。

5.Windows10的字体文件格式是TTC,兼容TTF,使用ttf字体文件有一定概率失常。

6.尽量使用纯白色背景的图片来当背景图,不然根本看不出轮廓。

7.url,class后面要加_,不然一堆报错。

总结

写这个爬虫的时候暴露出了我的python基础很不好,需要再学好python。

爬虫是很有趣的东西,我会继续去学习更深入、更厉害的知识技能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值