scrapy爬虫整理的一些知识点

本文记录自己在近期写scrapy项目中遇到的一些知识点,比较容易漏掉,也可能不常用,留作大家参考。

一:xpath选取某一个节点的后邻兄弟节点

//html代码片段如下
<li class="total_comment">123456li>
<li>hello worldli>
<li>        li>
<a href="www.example.com">中国好声音a>

使用following-sibling::* ,它的意思是某个元素后面的全部元素,是一个list形式返回,当我们的目标是class为total_comment后面的第一个li元素时:
//li[@class=”total_comment”]/following-sibling::*[1]
你可以使用相对下标来操作和这个元素同级的任何一个或者全部的后邻兄弟节点。

二:使用requests访问json数据操作

在使用scrapy抓取一些动态页面中,有时候会漏掉一些数据,大多是一些ajax传递的值,这个时候我按照正常的scrapy流程,我要么就再写一个parse函数,再往下一层去访问那个页面,再将拿到的数据和上一层的汇总,得到一个完整的items,但是无疑,这样的方法增加了爬虫的一层深度,会使得其变得更加低效并且繁琐,于是我考虑直接在最后的那个parse方法中再构造一个目标页面的url(需要自己去找接口,一般来说是xhr中的一些请求,也可能只是正常js执行的请求动作),访问拿回来的数据再填充到items中。

import requests

url = Get_Json_Url(args....)    #根据你找到的接口去设定一些参数,构造目标url
r = requests.get(url)
res = r.json()                  #返回的是一个dict,就能直接操作了,用   key - value来操作

三:lambda和map函数的混合使用

在开始我的代码中存items值的时候,我使用的是ItemLoader,从外面的配置文件中读取一个dict Final_Xpath,Final_Xpath的key作items的key,value是一个xpath表达式,通过这样的代码:

//这个Final_Xpath是从外部读入的,为了清晰一些直接写出来了
Final_Xpath = {"site_name":["//a[@id=\"target_title\"]/text()"],
                "movie_name":["//li[@class=\"p-row p-title\"]/text()"]
                }
item = YourSpiderItem()
for key in Final_Xpath.keys():
    item.fields[key] = Field()
    map(lambda x:l.add_xpath(key , x),Final_Xpath[key])

这样就能对每个key中的xpath list进行全部的提取,而不需要使用for x in Final_Xpath[key],简化了一点代码。本人的代码自认是很水的,对于灵活运用lambda以及其他py的黑科技还大大有待提高。

四:关于json文件中的load和loads区分

这个在踩了一些坑之后,还是觉得有必要拿出来提醒一下自己的。

import json

#load是接收的file类型的文件参数
json.load(open('somefile.json','r'))

#loads接收的已经dumps之后的json数据,也就是encode后的json字符串
json.loads(dumps_json)

注意:
1.在load某个open file的时候,要千万注意,被open的文件必须是正确的dict格式,并且只能是一个dict。(注意只能是一个,多个会报错)

2.loads接收的参数是在程序中的encoded_json字符串,也就是一个dict被json.dumps() encode之后得到的,这就很难直接拿到了,最好是用json.dumps()处理一下,才能得到loads需要的参数。

//标准格式的json字符串如下

a = {'movie_name': ['//li[@class="p-row p-title"]/text()'],
 'site_name': ['//a[@id="target_title"]/text()']}

json.dumps(a)
>>>Out[76]: '{"site_name": ["//a[@id=\\"target_title\\"]/text()"], "movie_name": ["//li[@class=\\"p-row p-title\\"]/text()"]}'

总结:
load是针对open file的;loads(好记一点:load str)是针对字符串(由json dumps而成)。在编写代码中避免错误操作,记住这些还是有很多帮助的。

暂时先写这些了,路途还很长,以后会遇到更多的坑和黑科技,加油。

你可能感兴趣的:(scrapy)