Python爬虫总结(CSS,Xpath,JsonLoad;静态网页,JS加载
优采云 发布时间: 2020-08-18 21:25Python爬虫总结(CSS,Xpath,JsonLoad;静态网页,JS加载
前言
随着人类社会的高速发展,数据对各行各业的重要性,愈加突出。爬虫,也称为数据采集器,是指通过程序设计,机械化地对网路上的数据,进行批量爬取,以取代低效的人工获取信息的手段。
1. 道德法律问题
爬虫目前在法律上尚属黑色地段,但爬别的网站用于自己的商业化用途也可能存在着法律风险。非法抓取使用“新浪微博”用户信息被判赔200万元,这是国外的一条因爬虫被判败诉的新闻。所以各商业公司还是悠着点,特别是涉及隐私数据。
大型的网站一般还会有robot.txt,这算是与爬虫者的一个合同。只要在robot.txt容许的范围内爬虫就不存在道德和法律风险。
2. 网络爬虫步骤2.1 检查API接口
API是网站官方提供的数据插口,如果通过调用API采集数据,则相当于在网站允许的范围内采集。这样既不会有道德法律风险,也没有网站故意设置的障碍;不过调用API插口的访问则处于网站的控制中,网站可以拿来收费,可以拿来限制访问上限等。整体来看,如果数据采集的需求并不是太奇特,那么有API则应优先采用调用API的形式。如果没有,则选择爬虫。
2.2 数据获取渠道剖析
页面收录数据
这种情况是最容易解决的,一般来讲基本上是静态网页,或者动态网页,采用模板渲染,浏览器获取到HTML的时侯早已是收录所有的关键信息,所以直接在网页上见到的内容都可以通过特定的HTML标签得到。
JavaScript代码加载内容
虽然网页显示的数据在HTML标签上面,但是指定HTML标签下内容为空。这是因为数据在js代码上面,而js的执行是在浏览器端的操作。当我们用程序去恳求网页地址的时侯,得到的response是网页代码和js的代码,因此自己在浏览器端能看到数据,解析时因为js未执行,指定HTML标签下数据肯定为空。这个时侯的处理办法:找到收录内容的js代码串,然后通过正则表达式获得相应的内容,而不是解析HTML标签。
Ajax异步恳求
这种情况是现今太常见的,尤其是在数据以分页方式显示在网页上,并且页面无刷新,或者是对网页进行某个交互操作后得到数据。所以当我们开始刷新页面的时侯就要开始跟踪所有的恳求,观察数据究竟是在哪一步加载进来的。然后当我们找到核心的异步恳求的时侯,就只用抓取这个异步恳求就可以了,如果原创网页没有任何有用信息,也没必要去抓取原创网页了。
2.3 页面数据结构剖析
结构性数据
结构化的数据是最好处理,一般都是类似JSON格式的字符串,直接解析JSON数据就可以了,提取JSON的关键数组即可。
page = requests.get(url)
headers = {}
page.encoding = 'utf-8'
data =re.findall(r'__INITIAL_STATE__=(.*?)',page.text)[0]
json_data = json.loads(data)
print(json_data)
#f = open('结果2.txt', 'w',
encoding='utf-8') # 以'w'方式打开文件
#for k, v in json_data.items():
# 遍历字典中的键值
#s2 = str(v) # 把字典的值转换成字符型
#f.write(k + '\n') # 键和值分行放,键在单数行,值在双数行
#f.write(s2 + '\n')
jobList = json_data['souresult']['Items'] #打印json_data,抓到关键词
for element in jobList:
print(f"===公司名称:{element['CompanyName']}:===\n"
f"岗位名称:{element['DateCreated']}\n"
f"招聘人数:{element['JobTitle']}\n"
f"工作代码:{element['JobTypeName']}\n"
f"公司代码:{element['RecruitCount']}\n"
f"详细信息URL:{element['SocialCompanyUrl']}")
非结构性数据-HTML文本数据
HTML文本基本上是传统爬虫过程中最常见的,也就是大多数时侯会碰到的情况。例如抓取一个网页,得到的是HTML,然后须要解析一些常见的元素,提取一些关键的信息。HTML虽然理应属于结构化的文本组织,但是又由于通常我们须要的关键信息并非直接可以得到,需要进行对HTML的解析查找,甚至一些字符串操作就能得到,所以还是归类于非结构化的数据处理中。常见解析方式:
CSS选择器
现在的网页式样比较多,所以通常的网页就会有一些CSS的定位,例如class,id等等,或者我们按照常见的节点路径进行定位。
item = soup.select('#u1 > a')
#选择指定目录下所有css数据
#print([i for i in item]) #print里添加循环时,记得加方括号
item = soup.select_one('#u1 > a') #选择指定目录下第一条 css数据
print(item)
Findall
##招聘人数
recru_num = soup.find_all('div', attrs={'class':'cityfn-left'}) #找到页面中a元素的所有元素,并找到a元素中 属性为'class=value'———————— attrs={"class": 'value'}
print(recru_num)
dr = re.compile(r']+>', re.S)
data = dr.sub('', str(recru_num)) #过滤HTML标签
print(data)
Xpath
html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/text()') #获取某个标签的内容(基本使用)
正则表达式
正则表达式,用标准正则解析,一般会把HTML当作普通文本,用指定格式匹配。当相关文本是小片断文本,或者某一串字符,或者HTML收录javascript的代码,无法用CSS选择器或则XPATH。
import re
a = '<p>[Aero, Animals, Architecture,Wallpapers">Artistic</a>, ........(省略)......... Vintage]'
titles = re.findall('