Scrapy的循序渐进的实现
之前有学习的scrapy对股票数据的爬取是一个浅显的实现,没有应用到反爬虫和item类型的实现。scarpy的强大需要不断的摸索,所以继续自主的实现scrapy的各种功能是十分必要的。
这里的实现学习没有对反爬虫机制,对动态页面的爬取以及多网站页面进行爬取,也没有使用item loader等一些高级用法,下一步学习scrapy-splash
由于爬虫的输出数据可能会很多,所以需要uedit来快速查看数据文件。
由于我们是用作学习,所以可以把setting中的ROBOTSTXT_OBEY设置为False这样就可以不被自己的scrapy所限制了
#setting.py下
ROBOTSTXT_OBEY = False
xpath的格式
上次工程使用的是css的解析方式,但是除此之外xpath的解析方式也是需要掌握的,具体语法格式网上都有,下面给出一个简单的概述。
question # 选取所有 question 元素的所有子节点
/question #选取根元素 question
question/a # 选取 question 元素下所有为 a 的子元素
//div # 选取所有的 div 元素,不论其出现在文档的任何地方
question//div # 选取 question 元素下所有的 div 后代元素 (/ 选取的是直接子元素,这里是所有的后代元素)
question//span/text() #选取 question 元素下所有 span 元素中的文本值
question//a/@href #选取 question 元素下所有 a 元素中的 href 属性值。 @ 后面可以是任意属性名,均可以取到值
/question/div[1] # 选取 question 的第一个 div 子元素。 注意这里第一个是从索引 1 开始的
/question/div[last()] # 选取 question 第最后一个 div 子元素
/question/div[last()-1] # 选取 question 的倒数第二个 div 子元素
//div[@lang] # 选取所有拥有lang 属性的 div 元素
//div[@lang='eng'] # 选取所有 lang 属性为 eng 的 div 元素
具体的学习(实现)步骤阶段一
阶段一是对如下界面的爬取。
url = "http://quote.eastmoney.com/stocklist.html"
这个url是东方财富网将所有股票基金列出的列表,页面内容非常简单,是第一阶段只对单一页面分析学习的好例子。
关于基础工程建立这里不再赘述。
step1: 打出目标页面的所有内容以分析
这一阶段是我们需要对整个页面做一个整体分析。需要利用的是response.body直接打出,在爬虫文件中写下如下代码。(response.body的type是bites,所以使用”w”这一读写mode肯定会出错)
class SumSpider(scrapy.Spider):
name = 'sum'
#allowed_domains = ['www.baidu.com']
start_urls = ['http://quote.eastmoney.com/stocklist.html']
def parse(self, response):
#print(type(response.body))
with open('out_body.txt', 'wb') as f:
f.write(response.body)
从结果可以知道所有的股票名称和代码都在\< a >标签下,所以需要查看所有的a标签下的内容。
step2: 打出所有的a标签下的内容
这里就是应用一下上面的xpath的语法,不过需要注意的是//a是选取所有a标签.//a才是选取所有的当前子节点下所有的a标签。而其会返回一个SelectorList类型(下面代码中的ans),所以需要遍历,而遍历的结点的类型是Selector(下面代码中的a),所以在用的时候需要extract()一下,得到一个str类型的元素(下面代码中的conte)。
class SumSpider(scrapy.Spider):
name = 'sum'
#allowed_domains = ['www.baidu.com']
start_urls = ['http://quote.eastmoney.com/stocklist.html']
def parse(self, response):
ans = response.xpath('.//a')
#print(type(ans))
#for a in ans:
#conte = a.extract()
#print(type(conte))
#print(type(a))
with open('out_a.txt', 'a') as f:
for a in ans:
conte = a.extract()
f.write(conte)
step3: 打出所带有href元素的a标签的内容
同样也是对xpath定位元素的使用,可以打出整个a元素,不过也要掌握只打出href的方法。
class SumSpider(scrapy.Spider):
name = 'sum'
#allowed_domains = ['www.baidu.com']
start_urls = ['http://quote.eastmoney.com/stocklist.html']
def parse(self, response):
ans = response.xpath('.//a[@href]')#('.//a/href')就是只打出href('.//a/text()')是打出所夹带的文本内容。
with open('out_af.txt', 'w')as f:
for a in ans:
f.write(a.extract() + '\n')
step4: 打出带有href元素且内容是我们想要得到的目标的元素内容
在上一步的基础上应用一下re的方法,可以定位目标元素。但是这里注意一下括号是需要用’(‘和’)’来表示的,具体规则还需参看re库的用法。
import scrapy
import re
class SumSpider(scrapy.Spider):
name = 'sum'
#allowed_domains = ['www.baidu.com']
start_urls = ['http://quote.eastmoney.com/stocklist.html']
def parse(self, response):
ans = response.xpath('.//a[@href]')#('.//a/@href')('.//a/text()')
listt = []
for a in ans:
stock = a.extract()
#print(stock)
try:
name = re.findall(r'>.*\(', stock)[0][1:-1]
#print(name)
id = re.findall(r'\(.*\)', stock)[0][1:-1]
#print(2)
strr = name + '-' + id
listt.append(strr)
except:
print('error')
with open('out_id_name.txt', 'w') as f:
for i in range(len(listt)):