背景:领导让统计点东西,之前一个页面的都用JS操作的,这次不行了:要跳2个页面才能获取到数据(我的思路是先从第一个页面获取所有超链接放到一个数组里,然后循环遍历,取第二个页面里的数据)。然后决定用刚学的PYTHON上手。(其实我这个整体思路就错了,应该直接通过接口取数据;而不是通过页面URL;因为URL有可能是动态生成的数据,就算获取到了url解析出来了,数据也是不全的...但也算加深学习python了)
思路:首先就是把请求头(包括cookie)放在header里登录网页。第二步是获取A标签。
from bs4
import BeautifulSoup
from urllib import request
import urllib.request
import chardet
import zlib
import requests
#1 数据url
url ="https://gxxxx.xxxx.cn/xxxxx"
#2 添加请求头
header = {
"method":"POST",
"accept":"application/json, text/plain, */*",
"accept-encoding":"gzip, deflate, br",
"accept-language":"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"content-type":"application/json;charset=UTF-8",
"cookie":"xxxxxxxxxxxxxxxxxxx",
}
#3 构建请求对象
request = urllib.request.Request(url, headers=header)
#4 发送请求对象
response = urllib.request.urlopen(request)
#5 读取并解析GZIP格式的页面(这里踩过坑,一开始解析出是都是乱码;后来知道是因为gzip格式导致的;处理方式如下)
data = zlib.decompress(response.read(), 16+zlib.MAX_WBITS)
#打印data
print(data)
#调试打印解析出的文件的格式是什么
print (chardet.detect(data).get('encoding'))
soup = BeautifulSoup(data, 'html.parser', from_encoding='iso-8859-1')
print(soup.decode('UTF-8'))
# 找出所有的 a 标签, 因为所有的链接都在 a 标签内
data = soup.find_all('a')
# 打开文件对象做持久化操作
file =open('D:/link.txt', mode='w', encoding='UTF-8')
# 遍历所有的 a 标签, 获取它们的 href 属性的值和它们的text
for itemin data:
if item.stringis not None and item['href'] !='javascript:;' and item['href'] !='#':
print(item.string, item.get('href'))
file.write(str.__add__(item.string, ' '))
file.write(str.__add__(item['href'], '\n'))
踩了3个坑:
1.一个是read源网页后,发现都是乱码;然后发现是gzip格式导致的;然后导入python的zlib库解决的。
然后还百度了--->打印解析出的文件的格式的指令:#print (chardet.detect(html).get('encoding'))
2.最开始写得那版,其实没有read,其实也是运行成功了的;但是我看着返回结果不太对,就又去read了一下源文件。然后出现了上述乱码问题。
第一版代码:
第二版代码:
3.成功解析出源码后,发现比源HTML少了好多数据。一查,发现有些数据是js后期加载生成的.....也就是说我这些都白写了。
参考文章:
用python代码模拟登录网站https://www.cnblogs.com/lanyincao/p/10745474.html
python来获取网页中的所有链接https://www.cnblogs.com/li1234567980/p/12846077.html
在python中使用urllib2.urlopen获取的html网页不完整https://segmentfault.com/q/1010000007513722