最近处于一种假期什么都不想的状态,正巧最近对外交部例行记者会的内容感兴趣,于是就想写个简单的爬虫把每次发布会的内容抓取下来,说不定之后再无聊的时候能用到啊2333,顺便复习一下python的爬虫,好久没用生疏了啊。
以上软件百度皆有详细的安装教程了,就不需要赘述了。
PS:在PyCharm里的File->Default Settings->Project Interpreter中可以比较方便的安装python的第三方库,在project Interpreter中选择你的python库然后点击下面的加好即可。
def getURL(url):
req = urllib.request.Request(url)
response = urllib.request.urlopen(req)
the_page = response.read().decode("UTF-8")
return the_page
如上5行代码即可把任意地址的网页解析成HTML文档的格式返回,如果print一下the_page就会发现,打印出来的就是该页面的源代码。
PS:response.read().decode("UTF-8")
一句中根据目标网页的编码格式可以灵活变更,防止因为python的编码问题影响进一步操作。
既然要写爬虫,我们就需要一点html的基本常识,我们通过chrome浏览器的查看源代码功能查看随意一个网站的源代码可以发现,一个html网站基本的结构大致为
<head>
<title>hello htmltitle>
...
head>
<body>
<a herf="hello.html">helloa>
...
body>
其中的
称为标签,而hello
之中的herf
则称为属性,简单的说html就是由标签层层嵌套所组成的,而属性则决定了这个标签的特殊性,而对于动态网页则可以用javascript和css的结合来做出各种酷炫的特效,这里就不再详述了。而理解了html的基本构成,也就可以开始初步的写一个简单的爬虫了。
首先我们需要了解,我们要抓取的内容在哪些页面上。
为此,我们访问中华人民共和国外交部首页->发言人表态->例行记者会,发现这是每天记者会记录的目录。我们通过改变页面发现,每一页的URL构成为
http://www.fmprc.gov.cn/web/fyrbt_673021/jzhsl_673025/
加上
default_?.shtml
其中的?表示页码-1,当为第一页时直接为default.shtml
,我们采用循环来生成我们需要访问的页面
i=0
while i<67:
url="http://www.fmprc.gov.cn/web/fyrbt_673021/jzhsl_673025/"
homeURL=url;
if i==0:
url+="default.shtml"
else:
url+="default_"+str(i)+".shtml"
the_page=getURL(url)
现在,我们已经得到了每一页html文档,接下来要做的就是解析该html,得到我们想要的内容
首先,我们采用Beautiful Soup来对网页进行解析
点我访问Beautiful Soup中文文档
soup = BeautifulSoup(the_page, 'html.parser')
通过该代码,我们可以把html文档解析成beautiful soup格式,通过beautiful soup对文档进一步操作。beautiful soup提供了find,select等多种方法供我们方便的定位到html文档中的任意位置,以便我们对该html进行处理。
data=soup.select("body div div div ul li a")
select选择器提供了多种规则进行选择。在此我们发现我们要从目录中找到具体的每一天记录的链接,为此对html文档进行分析发现,该链接全部处于body->div->div->div->ul->li->a标签下,我们采用了select选择器中的”标签A 标签B 标签C…”的方法来快速筛选出符合条件的html标签,data是一个列表,包含了所有满足条件的标签。
print(data)后我们发现,有部分标签也被选了进来,这时候我们看到我们需要的标签的格式都为xxxx主持例行记者会
,我们采取了一个简单的方法去掉噪音
for html_tag in data:
if "主持例行记者会" in html_tag.string:
通过判断主持例行记者会是否在我们搜索出的tag中,我们筛去了之前选出来的错误数据,接下来便是获取到具体的URL:
title=html_tag.string;
fileURL=homeURL+html_tag['href'][2:]
其中我们采用了该标签的字符串作为标题,并对URL进行了剪切方便加入之后的地址,然后我们就可以构造每天的具体内容的URL了。之后便是同样的方法
#下载网页
file_the_page = getURL(fileURL)
#beautiful soup解析
file_soup = BeautifulSoup(file_the_page, 'html.parser')
#采用find方法找到id为News_Body_Txt_A的部分(文档内容)
data1=file_soup.find("div",id="News_Body_Txt_A")
#打开txt,准备写入文档
f = open("result/"+title+".txt", "w", encoding='utf-8')
继续分析目标网页发现, 对于问的部分网站采用了 内容 内容
的嵌套结构来显示,而回答的部分则
直接嵌套的P标签下,为此我们分情况对其进行处理
for file_page in data1:
#如果该tag没有内容,则说明是问题的段
if file_page.string==None:
#可能有多个b标签,因此需要循环
temp_data=file_page.find_all('')
#采用一个result来进行合并
result=""
for temp_file in temp_data:
try:
#把每部分的内容加到result上
result+=temp_file.span.string
except (TypeError,AttributeError):
continue
#如果result不是空就输出
if (result!=""):
print(result,file=f)
#该tag有内容且不是换行符则直接写入文件
elif file_page.string!="\n":
print(file_page.string,file=f)
print(title+"Done!")
由此,我们基本上完成了一个对静态网页(外交部例行记者会)内容抓取的爬虫。
完整的代码请点击此处