scrapy爬取list页面下级详细页的翻页,及mysql相关

cashwar 发布于 2016/05/09 19:17
阅读 2K+
收藏 1
问题描述:


想抓取某类列表页中的新闻详细页,其中遇见有的新闻详细页有翻页,就是一长篇文章用分页来隔开,有的则没有。而我想储存的mysql每行字段格式如下:


domain, url, 标题, 简介,  全部翻页内容


这样才能方便生成网页,如果每个翻页都是一行,那我想不到要怎么调用。我自己想的是能不能把所有翻页正文都写到item的一个key里,然后直接存到mysql中即可。mysql是实现了,但是spider.py总是不能实现,卡了好几天。。。还希望大家指点。 : )


目前逻辑为:生成所有list页面翻页 -> 捕获新闻页url -> 获取指定数据, 提取翻页链接回调给翻页解析函数


list页面:http://www.cyone.com.cn/Article/chuangyegushi/pp/

有翻页的新闻详细页:http://www.cyone.com.cn/Article/Article_39110.html   #List页面中的第二条新闻



spider.py 如下:


# -*- coding:utf-8 -*-

import scrapy
from seo.items import SeoItem
from scrapy.http import Request
#from scrapy.loader import ItemLoader

class DmozSpider(scrapy.Spider):

    name = 'seo'
    start_urls = []

    #获取全部翻页链接
    for pn in range(1,16):
        url = 'http://www.cyone.com.cn/Article/chuangyegushi/pp/List_%s.html' % pn
        start_urls.append(url)

    #获取每页的新闻URL    
    def parse(self,response):
        urls = response.xpath('//*[@class="box4_a"]/a/@href').extract()
        for url in urls:
            url_new = 'http://www.cyone.com.cn' + url
            print ">>newsurl: %s" % url_new
            yield Request(url_new,callback=self.parse_item)
     
    #抓取新闻详细页内容
    def parse_item(self,response):
        item = SeoItem()
        item['domain'] = 'http://www.cyone.com.cn'
        item['url'] = response.request.url
        item['title'] = response.xpath('//*[@class="title4"]').extract()[0]
        item['summary'] = response.xpath('//*[@class="FIELDSET"]').extract()[0]
        item['content'] = response.xpath('//*[@class="left_co"]').extract()[0]

        pagelink = response.xpath('//*[@class="left_co"]//b/a/@href').extract() #获取详细页翻页链接

        if not pagelink: 
            self.log(">>> url: %s is not page!!" % response.url)
            item['page_content'] = "no"

        for link in pagelink: 
            link_new = 'http://www.cyone.com.cn' + link
            print ">>>>>>>> link_new: %s" % link_new
            yield Request(link_new,callback=self.parse_page,meta={'item':item}) #制定parse_page为回调,并传递item

    def parse_page(self,response):
        item = response.meta['item']
        item['page_content'] = response.xpath('//*[@class="left_co"]').extract()[0]
        yield item



写入mysql的piplines.py:



#coding:utf-8

import MySQLdb
import json  
import codecs
import re

class MySQLStorePipeline(object):
    def __init__(self):
        self.conn = MySQLdb.connect("localhost", "root", "!QAZxsw2", "seo", charset="utf8", use_unicode=True)
        self.cursor = self.conn.cursor()

    def process_item(self, item, spider):
        try:
            self.cursor.execute("""INSERT INTO testnews (domain, url, title, summary, content, page_content) 
                                VALUES (%s, %s, %s, %s, %s, %s)""",
                                (item['domain'],
                               item['url'],
                               item['title'], 
                               item['summary'],
                               item['content'],
                               item['page_content']))

            self.conn.commit()

        except MySQLdb.Error, e:
            print "Error %d: %s" % (e.args[0], e.args[1])
        return item




加载中
0
mickelfeng
mickelfeng
你好,文章分页问题解决了吗?
0
sting_bo
sting_bo

也碰到类似的问题了

0
Kalyter
Kalyter

我发现你现在代码中的一个问题:

1.我特地查看了一下这个网站,他们列表的URL规则并不是按照从1到n的方式,而是杂乱无章的,所以,不能直接循环1到16,你可以试一试List_1的页面,打开是什么都没有的。

解决方案:

    1.实际的请求首页;

    2.抓到下一页的URL xpath('//div[class="showpage"]/a[contains(text(), "下一页")]/@href '),再请求这个真实的下一个URL,这样可以遍历完所有的URL;

针对想把详情页的所有内容保存在MySQL的一个字段中的问题,我有一个解决方案:

    1.在解析详情页面的时候,解析完当前页面数据之后,获取到详情页面的下一页的URL    xpath(‘//p/b/a[contains(text(), "下一页")]/@href ')

    2.yield下一页的这个URL

    3.item.conent += 解析的内容

    4.判断是否还存在下一页,如果还有,则重复第1步,如果没有了,则yield item,在pipeline里面保存到MySQL。

返回顶部
顶部