>  기사  >  백엔드 개발  >  Python 크롤러를 처음부터 시작하는 방법에 대한 빠른 가이드

Python 크롤러를 처음부터 시작하는 방법에 대한 빠른 가이드

阿神
阿神원래의
2017-01-23 16:45:241264검색

서문

이 글의 주요 내용: 포럼 게시물 제목과 게시물 내용을 크롤링할 수 있는 가장 간단한 크롤러를 최단 시간에 작성합니다.

이 기사의 대상: 크롤러에 대해 글을 써본 적이 없는 초보자입니다.


시작하기

0. 준비

준비해야 할 것: Python, scrapy, IDE 또는 기타 텍스트 편집 도구.

1. 기술부서에서 연구한 결과 크롤러를 작성하기로 결정했습니다.

작업 디렉터리를 마음대로 만든 다음 명령줄을 사용하여 프로젝트를 만듭니다. 프로젝트 이름은 miao이며 원하는 이름으로 바꿀 수 있습니다.

scrapy startproject miao

그러면 scrapy로 생성된 다음 디렉터리 구조를 얻게 됩니다.

Python 크롤러를 처음부터 시작하는 방법에 대한 빠른 가이드

spready 폴더에 생성됨 Python 파일 , 예를 들어 miao.py는 크롤러 스크립트 역할을 합니다. 내용은 다음과 같습니다.

아아아아

2. 한번 해보시겠어요?

명령줄을 사용하면 다음과 같습니다.

import scrapy
class NgaSpider(scrapy.Spider):
    name = "NgaSpider"
    host = "http://bbs.ngacn.cc/"
    # start_urls是我们准备爬的初始页
    start_urls = [
        "http://bbs.ngacn.cc/thread.php?fid=406",
    ]
    # 这个是解析函数,如果不特别指明的话,scrapy抓回来的页面会由这个函数进行解析。
    # 对页面的处理和分析工作都在此进行,这个示例里我们只是简单地把页面内容打印出来。
    def parse(self, response):
        print response.body

Reptile Jun이 성간 영역의 첫 페이지를 인쇄한 것을 볼 수 있습니다. 처리가 없으므로 html 태그와 js 스크립트가 혼합되어 함께 인쇄됩니다.


분석

다음으로 방금 캡처한 페이지를 분석해야 합니다. 이 html과 js에서 Duili가 추출한 이 페이지의 게시물 제목입니다. 실제로 페이지를 구문 분석하는 것은 힘든 작업이며, 여기서는 xpath만 소개합니다.

0. 마법의 xpath를 사용해 보는 것은 어떨까요

방금 잡은 것을 살펴보거나, 크롬 브라우저로 수동으로 페이지를 열고 F12를 누르면 됩니다. 페이지 구조를 참조하세요. 각 제목은 실제로 이러한 html 태그로 래핑됩니다. 예를 들면 다음과 같습니다.

cd miao
scrapy crawl NgaSpider

href가 이 게시물의 주소이고(물론 포럼 주소가 앞에 철자가 와야 함) 이 태그로 묶인 콘텐츠가 게시물의 제목임을 알 수 있습니다.
그래서 우리는 xpath의 절대 위치 지정 방법을 사용하여 class='topic'인 부분을 추출했습니다.

1. xpath 효과 살펴보기

상단에 참조 추가:

<a href=&#39;/read.php?tid=10803874&#39; id=&#39;t_tt1_33&#39; class=&#39;topic&#39;>[合作模式] 合作模式修改设想</a>

분석 기능을 다음으로 변경:

from scrapy import Selector

다시 실행하면 포럼의 성간 영역 첫 페이지에서 모든 게시물의 제목과 URL을 볼 수 있습니다.


재귀

다음으로 각 게시물의 콘텐츠를 캡처해야 합니다. 여기서는 Python의 Yield를 사용해야 합니다.

 def parse(self, response):
        selector = Selector(response)
        # 在此,xpath会将所有class=topic的标签提取出来,当然这是个list
        # 这个list里的每一个元素都是我们要找的html标签
        content_list = selector.xpath("//*[@class=&#39;topic&#39;]")
        # 遍历这个list,处理每一个标签
        for content in content_list:
            # 此处解析标签,提取出我们需要的帖子标题。
            topic = content.xpath(&#39;string(.)&#39;).extract_first()
            print topic
            # 此处提取出帖子的url地址。
            url = self.host + content.xpath(&#39;@href&#39;).extract_first()
            print url

여기서 scrapy에게 이 URL을 크롤링한 다음 지정된 pars_topic 함수를 사용하여 크롤링된 페이지를 구문 분석하도록 지시합니다.

이제 게시물 내용을 분석하는 새로운 기능을 정의해야 합니다.

전체 코드는 다음과 같습니다.

yield Request(url=url, callback=self.parse_topic)

지금까지 이 크롤러는 포럼 첫 페이지의 모든 게시물 제목을 크롤링할 수 있으며 각 게시물의 첫 페이지에 있는 모든 제목을 크롤링할 수 있습니다. 1층의 콘텐츠. 여러 페이지를 크롤링하는 원리는 동일합니다. 페이지의 URL 주소를 구문 분석하고, 종료 조건을 설정하고, 해당 페이지 구문 분석 기능을 지정하는 데만 주의하세요.


파이프라인 - 파이프라인

여기서 크롤링 및 구문 분석된 콘텐츠를 처리하며 로컬 파일에 쓸 수 있습니다. 파이프를 통한 데이터베이스.

0. 항목 정의

miao 폴더에 items.py 파일을 만듭니다.

import scrapy
from scrapy import Selector
from scrapy import Request
class NgaSpider(scrapy.Spider):
    name = "NgaSpider"
    host = "http://bbs.ngacn.cc/"
    # 这个例子中只指定了一个页面作为爬取的起始url
    # 当然从数据库或者文件或者什么其他地方读取起始url也是可以的
    start_urls = [
        "http://bbs.ngacn.cc/thread.php?fid=406",
    ]

    # 爬虫的入口,可以在此进行一些初始化工作,比如从某个文件或者数据库读入起始url
    def start_requests(self):
        for url in self.start_urls:
            # 此处将起始url加入scrapy的待爬取队列,并指定解析函数
            # scrapy会自行调度,并访问该url然后把内容拿回来
            yield Request(url=url, callback=self.parse_page)

    # 版面解析函数,解析一个版面上的帖子的标题和地址
    def parse_page(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;topic&#39;]")
        for content in content_list:
            topic = content.xpath(&#39;string(.)&#39;).extract_first()
            print topic
            url = self.host + content.xpath(&#39;@href&#39;).extract_first()
            print url
            # 此处,将解析出的帖子地址加入待爬取队列,并指定解析函数
            yield Request(url=url, callback=self.parse_topic)
         # 可以在此处解析翻页信息,从而实现爬取版区的多个页面

    # 帖子的解析函数,解析一个帖子的每一楼的内容
    def parse_topic(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;postcontent ubbcode&#39;]")
        for content in content_list:
            content = content.xpath(&#39;string(.)&#39;).extract_first()
            print content
        # 可以在此处解析翻页信息,从而实现爬取帖子的多个页面

여기서 크롤링 결과를 설명하기 위해 두 가지 간단한 클래스를 정의합니다.

1. 처리 방법을 작성합니다

scrapy가 이전에 자동으로 생성되어 있었을 파이프라인.py 파일을 찾습니다.

여기서 처리 방법을 구축할 수 있습니다.

from scrapy import Item, Field
class TopicItem(Item):
    url = Field()
    title = Field() 
    author = Field()  
    
class ContentItem(Item):
    url = Field() 
    content = Field()
    author = Field()

2. 크롤러에서 이 처리 방법 을 호출합니다.

이 메소드를 호출하려면 크롤러에서만 호출하면 됩니다. 예를 들어 원래 콘텐츠 처리 기능을 다음과 같이 변경할 수 있습니다.

class FilePipeline(object):

    ## 爬虫的分析结果都会由scrapy交给此函数处理
    def process_item(self, item, spider):
        if isinstance(item, TopicItem):            ## 在此可进行文件写入、数据库写入等操作
            pass
        if isinstance(item, ContentItem):            ## 在此可进行文件写入、数据库写入等操作
            pass
        ## ... 
        return item

3. 구성 파일

settings.py 파일을 찾아

    def parse_topic(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;postcontent ubbcode&#39;]")        for content in content_list:
            content = content.xpath(&#39;string(.)&#39;).extract_first()            ## 以上是原内容
            ## 创建个ContentItem对象把我们爬取的东西放进去
            item = ContentItem()
            item["url"] = response.url
            item["content"] = content
            item["author"] = "" ## 略
            ## 这样调用就可以了
            ## scrapy会把这个item交给我们刚刚写的FilePipeline来处理
            yield item

를 추가하여 크롤러에서 호출하세요. "

ITEM_PIPELINES = {            &#39;miao.pipelines.FilePipeline&#39;: 400,
        }

는 이 FilePipeline에 의해 처리됩니다. 다음 숫자 400은 우선순위를 나타냅니다.
여기에서 여러 파이프라인을 구성할 수 있습니다. Scrapy는 우선순위에 따라 항목을 각 항목에 넘겨서 처리합니다.
다음과 같이 여러 파이프라인을 구성할 수 있습니다.

yield item


미들웨어——미들웨어

미들웨어를 통해 요청 정보를 일부 수정할 수 있습니다. 예를 들어 UA, 프록시, 로그인 정보 등 일반적으로 사용되는 설정은 미들웨어를 통해 구성할 수 있습니다.

0.미들웨어 구성

은 파이프라인 구성과 유사합니다.

ITEM_PIPELINES = {
            &#39;miao.pipelines.Pipeline00&#39;: 400,
            &#39;miao.pipelines.Pipeline01&#39;: 401,
            &#39;miao.pipelines.Pipeline02&#39;: 402,
            &#39;miao.pipelines.Pipeline03&#39;: 403,
            ## ...
        }

1. UA를 확인하려고 홈페이지를 깨뜨렸는데, UA를 바꾸고 싶어요

某些网站不带UA是不让访问的。在miao文件夹下面建立一个middleware.py

import random


agents = [
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5",
    "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.310.0 Safari/532.9",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7",
    "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1",
]


class UserAgentMiddleware(object): 

    def process_request(self, request, spider):
        agent = random.choice(agents)
        request.headers["User-Agent"] = agent

这里就是一个简单的随机更换UA的中间件,agents的内容可以自行扩充。

2.破网站封IP,我要用代理

比如本地127.0.0.1开启了一个8123端口的代理,同样可以通过中间件配置让爬虫通过这个代理来对目标网站进行爬取。同样在middleware.py中加入:

class ProxyMiddleware(object):
    def process_request(self, request, spider): 
        # 此处填写你自己的代理
        # 如果是买的代理的话可以去用API获取代理列表然后随机选择一个
        proxy = "http://127.0.0.1:8123"
        request.meta["proxy"] = proxy

很多网站会对访问次数进行限制,如果访问频率过高的话会临时禁封IP。如果需要的话可以从网上购买IP,一般服务商会提供一个API来获取当前可用的IP池,选一个填到这里就好。


一些常用配置

在settings.py中的一些常用配置

# 间隔时间,单位秒。指明scrapy每两个请求之间的间隔。
DOWNLOAD_DELAY = 5 

# 当访问异常时是否进行重试
RETRY_ENABLED = True 
# 当遇到以下http状态码时进行重试
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 403, 404, 408]
# 重试次数
RETRY_TIMES = 5

# Pipeline的并发数。同时最多可以有多少个Pipeline来处理item
CONCURRENT_ITEMS = 200
# 并发请求的最大数
CONCURRENT_REQUESTS = 100
# 对一个网站的最大并发数
CONCURRENT_REQUESTS_PER_DOMAIN = 50
# 对一个IP的最大并发数
CONCURRENT_REQUESTS_PER_IP = 50
我就是要用Pycharm

如果非要用Pycharm作为开发调试工具的话可以在运行配置里进行如下配置:
Configuration页面:
Script填你的scrapy的cmdline.py路径,比如我的是

/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py

然后在Scrpit parameters中填爬虫的名字,本例中即为:

crawl NgaSpider

最后是Working diretory,找到你的settings.py文件,填这个文件所在的目录。
示例:

Python 크롤러를 처음부터 시작하는 방법에 대한 빠른 가이드

按小绿箭头就可以愉快地调试了。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.