python爬虫入门超easy系列(三)
信息的抽取
使用xpath
1.什么是xpath
xml中,通向某个节点的一个路径,例如://div/ul/li/a,例子中为通向a节点的一个路径
2.基本用法:
取出所有的li中a节点的内容
#lxml.html.fromstring解析出的第一个节点是根节点
parse_result = lxml.html.fromstring(test_data)
#返回所有符合该路径的节点
a_elements = parse_result.xpath("//div/ul/li/a")
for a in a_elements:
print(a.text)
3.路径中//和/的区别
- ‘//’表示选中某个标签的所有后代,例如"//div//a",选中div后代的所有a标签,不管层次有多深
- '/'表示只选中某个标签的直系后代,例如"//div/a",只选中div儿子标签中为a的,只能一层间隔
4.递进方式的解析
parse_result = lxml.html.fromstring(test_data)
a_elements = parse_result.xpath("//book")
print(a_elements)
#注意在双斜线路径前的"."号表示当前路径
for a in a_elements:
print(a.xpath(".//title")[0].text)
5.选出某个属性
a_elements = parse_result.xpath("//book/title/@lang")
#注意a_elements现在存的是属性值,不再是lements对象,不用再使用a.text
for a in a_elements:
print(a)
6.直接选出标签内容
#使用text()内置函数可以直接选出标签内容,选出的结果是字符串数组
a_elements = parse_result.xpath("//book/title/text()")
print(a_elements)
for a in a_elements:
print(a)
7.其他常见用法总结
/ 从根标签开始 必须具有严格的父子关系
// 从当前标签 后续节点含有即可选出
* 通配符,选择所有
//div/book[1]/title 选择div下第一个book标签的title元素
//div/book/title[@lang="zh"]选择title属性含有lang且内容是zh的title元素
//div/book/title //book/title //title //div//title 具有相同的结果,因为使用相对路径最终都指向title
//book/title/@* 将title所有的属性值选择出来
//book/title/text() 将title的内容选择出来,使用内置text()函数
//a[@href="link1.html" and @id="places_neighbours__row"]
//a[@href="link1.html" or @id="places_neighbours__row"]
//div/book[last()]/title/text() 将最后一个book元素选出
//div/book[price > 39]/title 将book子标签price数值大于39的选择出来
//li[starts-with(@class,'item')] 将class属性前缀是item的li标签选出
//title[contains(@lang,'eng')] 将title属性lang含有eng关键字的标签选出
8.选出国家面积信息
import requests
import lxml.html
response = requests.get("http://example.webscraping.com/places/default/view/China-47")
parse_result = lxml.html.fromstring(response.text)
area = parse_result.xpath("//tr[@id='places_area__row']//td[@class='w2p_fw']/text()")
print("面积:",area[0])
8.注意事项
注意选出的元素是<Element a at 0x1031bbb88>这种类型还是字符串类型
使用CSS选择器
1.css选择器的常见用法
# " >" 相当于 "/" " " 相当于 "//"
parse_result = lxml.html.fromstring(test_data)
选择class=home的<a>标签: parse_result.cssselect("a.home")
选择id=game的<a>标签:parse_result.cssselect("a#home")
选择<a>标签的所有子标签span:parse_result.cssselect("a > span")
选择<a>标签的所有后代标签span:parse_result.cssselect("a span")
选择title属性为home的所有<a>标签:a[title=home]
选择class=home的所有标签 : parse_result.cssselect(".home")
2.选出国家面积
import requests
import lxml.html
response = requests.get("http://example.webscraping.com/places/default/view/China-47")
parse_result = lxml.html.fromstring(response.text)
area = parse_result.cssselect("tr#places_area__row td.w2p_fw")
print("面积:",area[0].text)
如何抓取大乐透中奖信息
import requests
import lxml.html
response = requests.get("http://trend.caipiao.163.com/dlt/")
parse_result = lxml.html.fromstring(response.text)
results = parse_result.xpath("//tr[@data-period]") #获取含有data-period属性的tr节点
reward_results = {}
for p in results:
result_key = p.xpath(".//@data-period")[0] #获取tr节点的data-period属性值
result_value = p.xpath(".//td[@data-omit=0 or @data-omit=-1]/text()")
reward_results[result_key] = result_value
print(reward_results)