모든 기사를 크롤링 거미로 작성 파이썬 프레임 워크 Scrapy 4-6 분산 크롤러

명령 행 :

scrapy shell https://news.cnblogs.com/

디버깅, URL의 모든 기사 페이지를 얻을 :

>>> articles_link_xpath = '//*[@class="news_entry"]/a/@href'
>>> articles_link_selector = response.xpath(articles_link_xpath)
>>> articles_link_selector
[<Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630083/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630082/'>, <Selector xpath=
'//*[@class="news_entry"]/a/@href' data='/n/630081/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630080/'>, <Selector xpath='//*[@class="news
_entry"]/a/@href' data='/n/630079/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630078/'>, <Selector xpath='//*[@class="news_entry"]/a/@href'
 data='/n/630077/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630076/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630075/
'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630074/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630073/'>, <Selector xpa
th='//*[@class="news_entry"]/a/@href' data='/n/630072/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630071/'>, <Selector xpath='//*[@class="n
ews_entry"]/a/@href' data='/n/630070/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630069/'>, <Selector xpath='//*[@class="news_entry"]/a/@hr
ef' data='/n/630068/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630067/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/6300
66/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630065/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630064/'>, <Selector
xpath='//*[@class="news_entry"]/a/@href' data='/n/630063/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630061/'>, <Selector xpath='//*[@class
="news_entry"]/a/@href' data='/n/630062/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630060/'>, <Selector xpath='//*[@class="news_entry"]/a/
@href' data='/n/630059/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630058/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/6
30057/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630056/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630055/'>, <Select
or xpath='//*[@class="news_entry"]/a/@href' data='/n/630054/'>]
>>> articles_link_list = articles_link_selector.extract()
>>> articles_link_list
['/n/630083/', '/n/630082/', '/n/630081/', '/n/630080/', '/n/630079/', '/n/630078/', '/n/630077/', '/n/630076/', '/n/630075/', '/n/630074/', '/n/630073/', '/n/
630072/', '/n/630071/', '/n/630070/', '/n/630069/', '/n/630068/', '/n/630067/', '/n/630066/', '/n/630065/', '/n/630064/', '/n/630063/', '/n/630061/', '/n/63006
2/', '/n/630060/', '/n/630059/', '/n/630058/', '/n/630057/', '/n/630056/', '/n/630055/', '/n/630054/']
>>> articles_link = ['https://news.cnblogs.com' + url for url in articles_link_list]
>>> articles_link
['https://news.cnblogs.com/n/630083/', 'https://news.cnblogs.com/n/630082/', 'https://news.cnblogs.com/n/630081/', 'https://news.cnblogs.com/n/630080/', 'https
://news.cnblogs.com/n/630079/', 'https://news.cnblogs.com/n/630078/', 'https://news.cnblogs.com/n/630077/', 'https://news.cnblogs.com/n/630076/', 'https://news
.cnblogs.com/n/630075/', 'https://news.cnblogs.com/n/630074/', 'https://news.cnblogs.com/n/630073/', 'https://news.cnblogs.com/n/630072/', 'https://news.cnblog
s.com/n/630071/', 'https://news.cnblogs.com/n/630070/', 'https://news.cnblogs.com/n/630069/', 'https://news.cnblogs.com/n/630068/', 'https://news.cnblogs.com/n
/630067/', 'https://news.cnblogs.com/n/630066/', 'https://news.cnblogs.com/n/630065/', 'https://news.cnblogs.com/n/630064/', 'https://news.cnblogs.com/n/630063
/', 'https://news.cnblogs.com/n/630061/', 'https://news.cnblogs.com/n/630062/', 'https://news.cnblogs.com/n/630060/', 'https://news.cnblogs.com/n/630059/', 'ht
tps://news.cnblogs.com/n/630058/', 'https://news.cnblogs.com/n/630057/', 'https://news.cnblogs.com/n/630056/', 'https://news.cnblogs.com/n/630055/', 'https://n
ews.cnblogs.com/n/630054/']

위의 코드에 의해, 우리는 필터 뒤에 문자열이 XPath를 적용 것을 볼 수있다 :

/@href

당신은 태그 내에 HREF 특성을 얻을 수 있습니다.

 

start_urls를로 복원

https://news.cnblogs.com/

위의 디버깅 모자이크를 달성하기 위해 URL 유형의 목록을 생성하는 데 사용됩니다 만, 제공 URLLIB 우리는 방법으로 완료됩니다.

다운로드에 문서 목록 페이지 문서 URL, scrapy을 획득 한 후, 구문 분석 특정 필드 : 코드 구현 구문 분석 기능, 즉 다음 첫 번째 함수.

from scrapy.http import Request
from urllib import parse

읽기 기능을 구문 분석 :

    def parse(self, response):
        """
        1. 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        2. 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        """
        # 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        articles_link = response.xpath('//*[@class="news_entry"]/a/@href').extract()
        for url in articles_link:
            yield Request(url=parse.urljoin(response.url, url), callback=self.parse_detail)
            pass

상기 코드는 먼저 더 융통성 urljoin 완전한 URL을 urljoin 의해 얻어진 for 루프에서, 스 플라이 싱 전에 XPath에 의해 URL을 파싱, URL 및 상기 요구에 파라미터로서 전달 된 콜백 함수하고 명령 수율 , 당신은 다운로드를 달성하고 콜백을 구문 분석 할 수 있습니다.

(다시 가져올 파일의 시작 부분에) 클래스 parse_detail 과정에서 캡슐화 된 특정 필드를 분석하기 전에 :

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        # 标题
        title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
        # 发布日期
        create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
        # 正文
        content = response.xpath('//*[@id="news_body"]').extract_first("No content")
        # 标签
        tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
        # 来源
        source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

        pass

 

다음과 같은 기능 즉, 두 번째 기능의 개발을 구문 분석 : 다운로드 scrapy를 다음 페이지의 URL을 가져, 다운로드가 구문 분석이 완료됩니다.

첫 번째는 쉘 디버그 scrapy입니다 :

>>> next_url_xpath = '//div[@class="pager"]/a[last()]/@href'
>>> next_url_selector = response.xpath(next_url_xpath)
>>> next_url_selector
[<Selector xpath='//div[@class="pager"]/a[last()]/@href' data='/n/page/2/'>]
>>> next_url = next_url_selector.extract_first()
>>> next_url
'/n/page/2/'

구문 분석 기능은 다음과 같은 논리를 추가합니다 :

        # 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        next_url = response.xpath('//div[@class="pager"]/a[not(@class)]/@href').extract_first('end')
        if next_url != 'end':
            next_url = parse.urljoin(response.url, next_url)
            yield Request(url=next_url, callback=self.parse)
        pass

위의 마지막 페이지로 주어진다는 다음 라벨 따라서 더 이상 마지막 ()를 사용, 더 이상 없다 획득하지 않지만 클래스 속성 태그를 선택하지 않는, 방법은 다음과 같습니다

/a[not(@class)]

전반적으로, 대한 cnblogs.py :

# -*- coding: utf-8 -*-
import scrapy
import re
from scrapy.http import Request
from urllib import parse


class CnblogsSpider(scrapy.Spider):
    name = 'cnblogs'
    allowed_domains = ['news.cnblogs.com']  # 允许的域名
    start_urls = ['https://news.cnblogs.com']  # 起始url

    def parse(self, response):
        """
        1. 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        2. 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        """
        # 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        articles_link = response.xpath('//*[@class="news_entry"]/a/@href').extract()
        for url in articles_link:
            yield Request(url=parse.urljoin(response.url, url), callback=self.parse_detail)
            pass

        # 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        next_url = response.xpath('//div[@class="pager"]/a[not(@class)]/@href').extract_first('end')
        if next_url != 'end':
            next_url = parse.urljoin(response.url, next_url)
            yield Request(url=next_url, callback=self.parse)
        pass

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        # 标题
        title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
        # 发布日期
        create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
        # 正文
        content = response.xpath('//*[@id="news_body"]').extract_first("No content")
        # 标签
        tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
        # 来源
        source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

        pass

우리가 scrapy을 사용하기 때문에, 작업 중 일부는 우리가 사용 URLLIB 또는 제작 요청하지 않아도, 그 주목해야한다. 우리가 콜백 메커니즘을 사용하는 것이 요청은 실제로 비동기입니다. 비동기 성능은 내용이 엄격한 순서의 같은 페이지가 아닌 들어오는 요청 URL의 순서에 따라되지 않습니다에 우리가 얻을 수 있다는 것입니다. 또한, 다른 페이지는 첫 번째의 첫 페이지의 내용의 대부분은 얻을 수있는 페이지의 뒤에서 앞 페이지가 나타납니다의 작은 부분을 얻을 수 있습니다.

파충류를 종료 할 때? 사실, 콜백은 재귀, 또는주기의 일종으로 볼 수있다. 당신은 사이클로 볼 때 종료 문제는 생각하기 어려운 더 이상 없을 때.

또한, 우리의 사이트 크롤링 및보기로 로그인이 필요하지 않습니다 거의 3 일간의 문서를 발견, 3 일 기사 전에이 장 우리의 그들은 우리가이 문제를 해결할 다음 장을 참조하기 전에 로그인 할 필요가있다한다 전용 콘텐츠의 거의 3 일 크롤링. 그래서, 다음 parse_detail를 다시 작성 :

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        if 'account' in response.url:
            pass
        else:
            # 标题
            title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
            # 发布日期
            create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
            # 正文
            content = response.xpath('//*[@id="news_body"]').extract_first("No content")
            # 标签
            tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
            # 来源
            source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

            pass

        pass

 

게시 된 101 개 원래 기사 · 원 찬양 26 ·은 10000 +를 볼

추천

출처blog.csdn.net/liujh_990807/article/details/100046015