首先,这是我第一次用scrapy在工作中,以前用过requests,但是那种小级别的东西,不适合网站级爬取,太慢了。
读到这句话的时候,我的代码已经写完了,项目已经完成了,现在对scrapy的使用做一个心得
scrapy:自动尝试错误,如果尝试3次还是失败则不管了,爬下一条。(不需要自己try,catch,congtinue)
遇到404,直接不爬取。(不需要自己判断)
总之很方便
先说需求吧:
https://rpmfind.net/linux/RPM/Groups.html
爬这个网站里的每一条。
点开一条
再爬里面的每一条
点开右边的一条,在爬里面的一条
总之就是爬3次,啪啪啪。
先不要慌张,先想一下思路。
我想用队列+爬虫的形式
将A爬完的结果存放到A队列中,A队列有多个消费者,进行消费,对每一个队列进行爬取。并且组装在集合中。(这样就不会因为多线程重复爬取了)
以下为scrapy爬虫入门(大佬们,不用看,直接去看下一个水平线的内容-不过还是建议简单过一下,这样你会更加清楚我在干嘛)
之前先的scrapy入门写的不好,我等会把他删除了。现在重新写一下。
首先创建scrapy项目(觉得好傻*,还是自动生成的项目,还要用命令)
点击terminal,输入
scrapy startproject 项目名称
于是,他创建了一个pachong的文件夹
来小伙伴们,我们点开pachong这个文件夹,看看里面(这个傻*命令,创建了什么东西)
首先
卧槽,文件夹中夹文件,很明显,我们能看到一个有洞的文件夹,以及1个scrapy.cfg(这个肯定是配置文件,你只要有一点点英语常识就知道,如果你不知道,建议你去买一本牛津词典,900页,全部背会,滚瓜烂熟,包你看词如有神在旁边指导一样)。
我们暂时不需要对scrapy.cfg进行配置
我们打开pachong中的pachong文件夹。
发现里面有这么多py文件 ,这些.py里面都有内容。我们先不管,此时打开spiders文件夹
在spiders文件夹中,创建你的爬虫。新建一个test1.py
用爬虫框架,就要遵守他的规则。编写下面的代码
import scrapy class test1(scrapy.Spider): #需要继承scrapy.Spider类 name = "test1_pachong" # 定义蜘蛛名
def start_requests(self): # 由此方法通过下面链接爬取页面 # 定义爬取的链接(数组) urls = [ 'http://lab.scrapyd.cn/page/1/', 'http://lab.scrapyd.cn/page/2/', ] for url in urls: yield scrapy.Request(url=url, callback=self.parse) #爬取到的页面如何处理?提交给parse方法处理(遍历交给parse方法去处理)
def parse(self, response): print('打印'+response.body)#打印结果
上面的只是demo,现在开始往实战上引入。
启动项目会自动运行start_requests,他为入口。
这里其他代码都很基础,除了这个yield scrapy.Request(url=url,callback=self.parse)
yield是代表的回调,就是执行到这里异步去执行其他的
scrapy.Requets是scrapy框架的请求方法,callback中self后面代表的此py脚本里面的方法,叫做parse的,当请求后,就会默认将reponse的结果,传入到此方法并且执行。
我们就通过来回的,回调,执行完n次层级爬取与解析。
目标站:https://rpmfind.net/linux/RPM/Groups.html
他是个html页面,并且没有json什么的,返回就是个html,我要获取所有的li中的内容,那就要用到文档解析的东西,xpath(他是最常使用的一种解析xml文档类型的小框架,当然也支持html解析,非常方便)
xpath基本操作参考:
https://www.cnblogs.com/lei0213/p/7506130.html
我现在想获取li中的a标签的全部href子连接、以及a标签中的内容
1.在py爬虫脚本 开头 导入xpath
from lxml import etree
2.在parse方法中
增加如下代码
html = etree.HTML(response.text) html_data_link = html.xpath('/html/body/ul/li/a/@href') # 获取href中的内容 html_data_content = html.xpath('/html/body/ul/li/a/text()') # 获取a标签中的内容
i = 0
for link in html_data_link: self.log('连接为' + link + '—内容为' + html_data_content[i]) # print('连接为'+link+'—内容为'+html_data_content[i]) i = i + 1
ok,我们来运行测试一下。在控制台输入(注意一定要在你之前用scrapy创建爬虫的目录下)
scrapy crawl 你代码中的name名称
往下翻,看看是否打印出来了
成功!!!
实例阶段
接下来爬取子连接,我们看到link是有问题的,他没有链接,是个不完整的人,所以我们给他补上
link='https://rpmfind.net/linux/RPM/'+link
接下来调用创建回调函数去请求连接(在回调之前打印,这样就知道我进入了一个地址,在爬取它的子连接)
print("我请求的网站是"+link) yield scrapy.Request(url=link, callback=self.parse1)
创建解析数据的方法parse1(并且打印)
def parse1(self, response): print('——————-') html = etree.HTML(response.text) html_data_link = html.xpath('/html/body/table[2]/tbody/tr/td/a/@href') # 获取href中的内容
for url in html_data_link: link='https://rpmfind.net'+url print(link)
运行,发现,没有达到我想要的,区分哪个连接是谁爬的效果(后面查阅资料,原来scrapy为了追求效率,进行多线,异步爬取) 。
现在已经解析完这层了
在继续的调研中,我发现点击刚刚我们获取到的地址,就是红色部分,可能会出现404的情况,以及有效数据的情况。
我们这里选取有效数据的内容进行保存,对于返回值产生404的结果进行过滤。
我测试了404界面,担心404会让代码报错,但是scrapy这点很强大啊,404直接不会执行里面的任何代码。
后面解析比较复杂,咱不描述了。要具体按F12分析,可以拿xpath慢慢解析
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试