2018年1月份初初认识了python,之前爬过一个影评一个小说。因为我本人是学java的,后来因为各种原因一直没怎么动过python。这次主要是领导有个小任务,所以我就尝试着爬了一下,所幸非常简单,还是记录一下。本文可能会引起大神不适,谨慎阅览。
可能以下内容有更简单的方法实现,也可能有不对的地方,请大神们指教
python的安装教地址http://blog.youkuaiyun.com/nmjuzi/article/details/79075736
结合久远的记忆,爬那种非常简单没有任何安全验证的网站只需要以下几步
1.抓取网页数据
2.分析网页构造
3.清理数据
4.根据自己的需要对数据进行整理
抓取网页数据
以此网站为例
http://ggzy.gz.gov.cn/html/zrzy/,把这些数据转为json输出
我们先请求一下下一页看他怎么请求数据的,点了下下一页发现他是直接请求的页面,分页参数用的是pages。这个页面还可以直接拿出去访问
以上参考,我们只要获取http://tkwz.gzggzy.cn/gtkcwz/module/wz/index_zzgg.jsp这个页面的数据就行了
# 引入urllib库
import urllib.request
getPage = urllib.request.urlopen('http://tkwz.gzggzy.cn/gtkcwz/module/wz/index_zzgg.jsp')
getPageHtml = getPage.read().decode('utf-8')
# 查看一下获取到的页面html
print(getPageHtml )
执行以下我们就可以在控制台看到网页的html代码
下面分析网页构造情况
对得到的html代码进行解析,提取我们需要的数据
在python中可以使用BeautifulSoup4库进行html代码的解析
需要先安装此库,非常简单按照教程二,我们只需要在命令窗口输入
pip install beautifulsoup4即可
按照完成后引入并对页面进行解析
from bs4 import BeautifulSoup
pageSoup = BeautifulSoup(getPageHtml, 'html.parser')
print(pageSoup)
现在我们来分析页面,这么多标签哪个是我们需要的?
我们用开发者模式选中这一块我们想要的数据,发现他们都被放在以class名mh_info_list命名的div块中
# 获取所有这些class名为mh_info_list的div块,获取后以数组的形式存放在divInfo中
divInfo = pageSoup.find_all('div', class_='mh_info_list')
print(divInfo)
再次分析网页,发现我们需要的数据被分为2部分,一部分放在class名为b的div块中,另一部分放在table中
我们以第一个mh_info_list块为例divInfo[0]
先获取class名为b的div块
b = divInfo[0].find('div', class_='b')
print(b)
输出一下b
发现我们要的数据还被括在一个span中,再来一次就是我们要的内容拉
spanText = b.find('span').text
print(spanText)
# 创建一个json
info_dict = {}
# 把获取到的第一个数据放到json中
info_dict['id'] = spanText
接着我们分析另一部分被放在table中的数据,这次我们直接看页面这些数据被放在table的tbody中
table = divInfo[0].find('table').find('tbody')
print(table)
通过查看输出的数据发现th和td是一一对应的,且分别被放在两个tr里面
# 先获取这两行数据
tr = table.find_all('tr')
# 获取tr里的th数据
th = tr[0].find_all('th')
# 获取tr里的td数据
td = tr[1].find_all('td')
上面也说到th和td是一一对应的,只要我们知道th的长度再进行遍历把th作为key,td作为value我们把表格数据转为json的任务就完成了
for num in range(0, len(th)):
info_dict[th[num].text] = td[num].text
print(info_dict)
以上我们第一个表格的数据都被处理完并输出了,我们只要在处理表格数据的时候遍历表格就能获取所有表格的数据。问题来了,我们这个页面有5页的数据呢,5页还是比较少,他有20页100页怎么办?
回到最初我们查看他这个页面,发现他有一个最后一页这个按钮,把一共有多少页告诉我们了
完整代码
# 引入urllib库
import urllib.parse
import urllib.request
from bs4 import BeautifulSoup
import re
# 定义最终输出的数组
page1info_list = []
# 获取一共有多少页
getPage = urllib.request.urlopen('http://tkwz.gzggzy.cn/gtkcwz/module/wz/index_zzgg.jsp')
getPageHtml = getPage.read().decode('utf-8')
pageSoup = BeautifulSoup(getPageHtml, 'html.parser')
pageDiv = pageSoup.find('div', id='pagediv')
endPage = pageDiv.find('a', id="endPage")
# 获取endPage里的数字内容
totalPage = re.sub("\D", "", endPage['onclick'])
print(totalPage)
# 遍历所有页面
for num in range(1, int(totalPage)+1):
# 动态传参进入下一页
data = bytes(urllib.parse.urlencode({'pages': num}), encoding='utf8')
page1resp = urllib.request.urlopen('http://tkwz.gzggzy.cn/gtkcwz/module/wz/index_zzgg.jsp', data=data)
html_data = page1resp.read().decode('utf-8')
page1soup = BeautifulSoup(html_data, 'html.parser')
page1info = page1soup.find_all('div', class_='mh_info_list')
# print(page1info)
for item in page1info:
b = item.find('div', class_='b')
spanText = b.find('span').text
# 创建一个json
info_dict = {}
# 把获取到的第一个数据放到json中
info_dict['id'] = spanText
table = item.find('table').find('tbody')
# 先获取这两行数据
tr = table.find_all('tr')
# 获取tr里的th数据
th = tr[0].find_all('th')
# 获取tr里的td数据
td = tr[1].find_all('td')
# -1的原因是最后一列操作列数无用数据
for num in range(0, len(th)-1):
info_dict[th[num].text] = td[num].text
page1info_list.append(info_dict)
print(page1info_list)