您的位置:首页 > 其它

scrapy实例

qq_28143929 2019-07-07 11:22 30 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_28143929/article/details/94871848

scrapy爬取http://www.cqn.com.cn/ms/node_1460.htm

1.先进入配置好的scrapy环境变量,用命令行创建scrapy项目

2.scrapy startproject 项目名,进入项目目录

3.scrapy genspider 爬虫名 所要爬取网页的根url

4.pycharm打开爬虫项目

5.更改settings.py文件中的

[code]ROBOTSTXT_OBEY = False

6.在 爬虫名.py文件中编辑爬虫的逻辑

start_urls放入所要爬取文件的起始网页的url

定义解析response函数,函数操作的对象就是对url爬取过后的response结果

一般对response用xpath规则进行解析

xpath语法教程 http://www.w3school.com.cn/xpath/index.asp

根据chrome浏览器->更多工具(L)->开发者工具(D)进入爬取url的Elements,通过对想要的元素经行分析定位写入函数

一般爬取url中显示的列表->找到url的Elements中的ul标签下的li生成一个包含li的list对象,对list进行for循环找到li中的想要信息

一般爬取url中显示的表格->找到url的Elements中的table标签下的tr生成一个包含所有tr的list对象,对list进行for循环找到tr标签下的td,再生成一个包含所有td的list,对list在进行一次for循环就可以找到td内的具体内容。爬取table需要2层for循环嵌套。

我觉得在爬取table表格是先生成一个空列表,在最内层for循环将爬取到的内容添加到空列表中,同时记录tr列表的长度和td列表的长度,这样容易对table表格进行还原,对具体数据进行定位。

 

对于爬取具体标签中的文本会有爬取不完全的情况,所以也需要先生成一个p标签下所有文本的list对象,对list进行for循环遍历,将每一段文本拼接在一起后返回。

response.xpath('//标签类型[@标签的一个属性=“属性具体的名字”]')  适合定位到拥有唯一属性名字的标签

.//表示从根目录下所有节点  

/表示当前节点的下一层节点

一般使用.// + 具体属性名进行定位

 

如果需要从当前url中跳转到url中包含的url需要用 yield response.follow(跳转的url,self.解析跳转url的函数名)

跳转的url不需要拼接成完成的url,只需要是从当前url中通过xpath语法定位到的a标签的href属性内容

一般爬虫会涉及的到爬取下一页的问题,可以将下一页的url做为一个变量,通过对这个变量进行if判断是否为空来判断是否存在下一页,如果不为空,就通过yield response.follow(跳转的url,self.解析跳转url的函数名)进行下一页的爬取。下一页如果为空爬取会报错,建议加一个异常处理。

 

一般爬取到的table表格内容需要生成csv文件好用来进行数据分析。

table表格中的数据都添加到了content列表中,先生成文件名,然后对csv文件进行写入。

csv文件每次要按行写入,所以每次写入数据的长度和爬取table表格中的tr,td两个列表的长度有关系。

 

[code]import csv
import requests
import scrapy

from CQN.items import CqnItem

class CqnSpider(scrapy.Spider):
name = 'cqn'
allowed_domains = ['cqn.com.cn']
start_urls = ['http://www.cqn.com.cn/ms/node_1460.htm']

#def start_requests(self):
#    url = ['http://www.cqn.com.cn/ms/node_1460.htm']
#    yield scrapy.Request(url,callback=self.parse)

def parse(self, response):

next_list = response.xpath('.//span[@class="curr"]/following::*')[0]

news_list = response.xpath('//dd[@class="cont_l"]/ul/li')
for news in news_list:
item = CqnItem()
time = news.xpath(".//span/text()").extract_first()
headline = news.xpath(".//a/text()").extract_first()
link = news.xpath(".//a/@href")[0]
yield response.follow(link,self.parse_content)

if next_list:
try:
yield response.follow(next_list, self.parse)
except ValueError:
print("---------------------------------------------------------")
else:
print(next_list)

def parse_content(self,response):
tables = response.xpath('.//table')
tag=1
for table in tables:
content = []
trs = table.xpath('.//tr')
num = (int(len(trs)) - 1)
for tr in trs:
tds = tr.xpath('.//td')
lens = (int(len(tds)))
if lens==1:
tag=0
for td in tds:
text = ""
for p in td.xpath('.//p//text()'):
text = text + p.extract().strip()
content.append(text)

if(len(content)>10):
if tag == 1:
x = response.xpath('.//div[@class="Detail_Title"]/h1/text()').extract_first()
y = str(x).split("\r\n")
z = y[1].split(" ")
content.insert(0, z[8])

title = content[0] + '.csv'
with open(title,'w',encoding='utf-8',newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(content[1:(lens+1)])
for i in range(num):
writer.writerow(content[(lens*(i+1)+1):(lens*(i+2)+1)])

 

标签: