本次爬取目标网站为 https://www.nanjixiong.com/forum-2-1.html
任务是爬取列表页+详情页数据
在爬取过程中发现几点问题:
- 每次运行scrapy爬取内容的顺序都不一致。
原因:百度原因是scrapy是一个异步处理框架,也就是说Scrapy发送请求之后,不会等待这个请求的响应(也就是不会阻塞),而是可以同时发送其他请求或者做别的事情。而我们知道服务器对于请求的响应是由很多方面的因素影响的,如猫之良品所说的网络速度、解析速度、资源抢占等等,其响应的顺序是难以预测的。 - 在使用普通的同步写入方法时,发现部分数据最后写不到数据库中。
原因:百度原因是同步异步(但我还不是很理解这个地方,如有大佬朋友清楚原因,请指教下本小白,感谢!!)。①同步: 同步写入数据速度比较慢, 而爬虫速度比较快,普通的mysql操作是同步操作,插入数据的速度(即I/O读写)远远低于spider中解析数据的速度。 可能导致数据最后写不到数据库中。②异步: 是将爬虫的数据先放到一个连接池中, 再同时将连接池的数据写入到数据库中, 这样既可以提高数据库的写入速度, 同时也可以将爬取到的所有数据都写到数据库中, 保证数据的完整性。
使用实现代码如下:
分别测试了延迟与正常状态下的同步写入和异步写入,效果如下
spider部分
import scrapy
import re
from copy import deepcopy
from up3Dprint.items import Up3DprintItem
class NanjixiongSpider(scrapy.Spider):
name = 'nanjixiong'
allowed_domains = ['nanjixiong.com']
start_urls = ['https://www.nanjixiong.com/forum-2-1.html']
def parse(self, response, **kwargs):
new_list = response.xpath('//*[@id="threadlisttableid"]/tbody')
for new in new_list:
item = Up3DprintItem()
item['id'] = new.xpath('./@id').extract_first()
item['title'] = new.xpath('./tr/th/div[1]/a[2]/text()').extract_first()
item['href'] = new.xpath('./tr/th/div[1]/a[2]/@href').extract_first()
yield scrapy.Request(
url='https://www.nanjixiong.com/' + item['href'],
callback=self.parse_detail,
meta={
'item':deepcopy(item)}
)
def parse_detail(self, resopnse):
item = resopnse.meta['item']
item['publish_year'] = resopnse.xpath('//*[@id="wp"]/div[2]/div[2]/div[1]/div/div[1]/b/text()').extract_first()
item['publish_month'] = resopnse.xpath('//*[@id="wp"]/div[2]/div[2]/div[1]/div/div[2]/text()').extract_first()
item['publish_date'] = resopnse.xpath('//*[@id="wp"]/div[2]/div[2]/div[1]/div/div[3]/text()').extract_first()
item['image'] = resopnse.xpath('//*[@id="ct"]//td[@class="t_f"]//ignore_js_op//img/@zoomfile').extract()
content = resopnse.xpath<