> 백엔드 개발 > 파이썬 튜토리얼 > Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

高洛峰
풀어 주다: 2016-11-07 16:43:35
원래의
1934명이 탐색했습니다.

배경:

PySpider: 강력한 WebUI를 사용하여 중국인이 작성한 강력한 웹 크롤러 시스템입니다. Python 언어로 작성되었으며 분산 아키텍처를 가지며 여러 데이터베이스 백엔드를 지원하고 강력한 WebUI는 스크립트 편집기, 작업 모니터, 프로젝트 관리자 및 결과 뷰어를 지원합니다. 온라인 예: http://demo.pyspider.org/

공식 문서: http://docs.pyspider.org/en/l...

Github: https:// github.com/binux/pysp...

이 기사의 크롤러 코드 Github 주소: https://github.com/zhisheng17...

더 흥미로운 기사를 찾을 수 있습니다. WeChat 공개 계정: Ape 블로그를 읽고 팔로우를 환영합니다.

이제 본문을 살펴보겠습니다!

전제조건:

이미 Pyspider와 MySQL-python을 설치했습니다(데이터 저장)

아직 설치하지 않으셨다면, 우회하는 일이 없도록 이전 글을 꼭 읽어보시기 바랍니다.

Pyspider 프레임워크를 배울 때 겪었던 몇 가지 함정

HTTP 599: SSL 인증서 문제: 로컬 발급자 인증서를 가져올 수 없음 오류

발생한 몇 가지 오류:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

우선 이 크롤러의 목표는 Pyspider 프레임워크를 사용하여 V2EX 웹사이트의 게시물에 있는 질문과 콘텐츠를 크롤링한 다음 크롤링된 데이터를 로컬에 저장하는 것입니다.

V2EX에서 대부분의 게시물을 보려면 로그인이 필요하지 않습니다. 물론 일부 게시물을 보려면 로그인이 필요합니다. (크롤링을 하다가 항상 오류가 발견되고, 구체적인 이유를 확인한 결과 해당 게시물을 보려면 로그인이 필요하다는 사실을 알게 되었기 때문에) 따라서 쿠키를 사용할 필요는 없다고 생각합니다. 로그인을 해야 하는데, 로컬 방식은 로그인 후 쿠키를 추가하는 방식으로 매우 간단합니다.

https://www.v2ex.com/을 검색한 결과 모든 게시물을 포함할 수 있는 목록이 없다는 것을 발견했습니다. 차선책으로만 결정하고 카테고리 아래의 모든 태그 목록을 크롤링할 수 있습니다. . 페이지를 방문하여 모든 게시물을 탐색하세요: https://www.v2ex.com/?tab=tech 그리고 https://www.v2ex.com/go/progr... 마지막으로 각 게시물의 자세한 주소는 (for) 예): https://www.v2ex.com/t/314683...

프로젝트 만들기

pyspider 대시보드 오른쪽 하단에서 "Create" 버튼을 클릭합니다.

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

on_start 함수에서 self.crawl의 URL을 바꾸세요.

@every(minutes=24 * 60) 
    def on_start(self): 
        self.crawl('https://www.v2ex.com/', callback=self.index_page, validate_cert=False)
로그인 후 복사

self.crawl은 pyspider에게 지정된 페이지를 크롤링하라고 지시한 다음 다음을 사용합니다. 결과를 구문 분석하는 콜백 함수.

@every) 수식어는 on_start가 하루에 한 번 실행되어 최신 게시물을 캡처할 수 있음을 나타냅니다.

validate_cert=False는 이와 같아야 합니다. 그렇지 않으면 HTTP 599: SSL 인증서 문제: 로컬 발급자 인증서를 얻을 수 없음 오류가 보고됩니다.

홈 페이지:

녹색을 클릭합니다. 실행하려면 다음 패널 위에 빨간색 1이 표시됩니다.

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

두 번째 그림 이 문제는 처음에 스크린샷에 나타났습니다. 해결방법은 앞서 작성한 글을 참고하시면 더 이상 문제가 발생하지 않습니다.

탭 목록 페이지:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

탭 목록 페이지에서는 모든 주제 목록 페이지의 URL을 추출해야 합니다. 샘플 핸들러가 매우 큰 URL

코드:

@config(age=10 * 24 * 60 * 60) 
    def index_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/?tab="]').items(): 
            self.crawl(each.attr.href, callback=self.tab_page, validate_cert=False)
로그인 후 복사

를 추출한 것을 발견했을 수 있습니다. 게시물 목록 페이지와 탭 목록 페이지의 길이가 다르기 때문에 여기에 생성됩니다. 콜백은 self.tab_page

@config(age=10 24 60 * 60)입니다. 이는 페이지가 10일 이내에 유효하다고 생각하고

을 업데이트하거나 크롤링하지 않는다는 의미입니다. 목록 페이지 다시 이동:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

코드:

@config(age=10 * 24 * 60 * 60) 
 
def tab_page(self, response): 
 
for each in response.doc('a[href^="https://www.v2ex.com/go/"]').items(): 
 
self.crawl(each.attr.href, callback=self.board_page, validate_cert=False)
로그인 후 복사

게시물 세부정보 페이지(T):

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

결과에 일부 응답 항목이 있는 것을 볼 수 있으며, 해당 항목은 필요하지 않으므로 제거할 수 있습니다.

동시에 자동 페이지 넘김 기능도 깨닫게 해줘야 합니다.

코드:

@config(age=10 * 24 * 60 * 60) 
    def board_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/t/"]').items(): 
            url = each.attr.href 
            if url.find('#reply')>0: 
                url = url[0:url.find('#')] 
            self.crawl(url, callback=self.detail_page, validate_cert=False) 
        for each in response.doc('a.page_normal').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
            #实现自动翻页功能
로그인 후 복사

제거 후 스크린샷:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

자동 페이지 넘김 구현 후 스크린샷:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

此时我们已经可以匹配了所有的帖子的 url 了。

点击每个帖子后面的按钮就可以查看帖子具体详情了。

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

代码:

@config(priority=2) 
    def detail_page(self, response): 
        title = response.doc('h1').text() 
        content = response.doc('p.topic_content').html().replace('"', '\\"') 
        self.add_question(title, content)  #插入数据库 
        return { 
            "url": response.url, 
            "title": title, 
            "content": content, 
        }
로그인 후 복사

插入数据库的话,需要我们在之前定义一个add_question函数。

#连接数据库 
def __init__(self): 
        self.db = MySQLdb.connect('localhost', 'root', 'root', 'wenda', charset='utf8') 
 
    def add_question(self, title, content): 
        try: 
            cursor = self.db.cursor() 
           sql = 'insert into question(title, content, user_id, created_date, comment_count)
            values ("%s","%s",%d, %s, 0)' % 
            (title, content, random.randint(1, 10) , 'now()');   
            #插入数据库的SQL语句 
            print sql 
            
            cursor.execute(sql) 
            print cursor.lastrowid 
            self.db.commit() 
        except Exception, e: 
            print e 
            self.db.rollback()
로그인 후 복사

查看爬虫运行结果:

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

先debug下,再调成running。pyspider框架在windows下的bug

设置跑的速度,建议不要跑的太快,否则很容易被发现是爬虫的,人家就会把你的IP给封掉的

查看运行工作

查看爬取下来的内容

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습Python 크롤러로 V2EX 웹사이트 게시물 크롤링 연습

然后再本地数据库GUI软件上查询下就可以看到数据已经保存到本地了。

自己需要用的话就可以导入出来了。

在开头我就告诉大家爬虫的代码了,如果详细的看看那个project,你就会找到我上传的爬取数据了。(仅供学习使用,切勿商用!)

当然你还会看到其他的爬虫代码的了,如果你觉得不错可以给个 Star,或者你也感兴趣的话,你可以fork我的项目,和我一起学习,这个项目长期更新下去。

最后:

代码:

# created by 10412 
# !/usr/bin/env python 
# -*- encoding: utf-8 -*- 
# Created on 2016-10-20 20:43:00 
# Project: V2EX 
 
from pyspider.libs.base_handler import * 
 
import re 
import random 
import MySQLdb 
 
class Handler(BaseHandler): 
    crawl_config = { 
    } 
 
    def __init__(self): 
        self.db = MySQLdb.connect('localhost', 'root', 'root', 'wenda', charset='utf8') 
 
    def add_question(self, title, content): 
        try: 
            cursor = self.db.cursor() 
          sql = 'insert into question(title, content, user_id, created_date, comment_count) 
         values ("%s","%s",%d, %s, 0)' % (title, content, random.randint(1, 10) , 'now()'); 
            print sql 
            cursor.execute(sql) 
            print cursor.lastrowid 
            self.db.commit() 
        except Exception, e: 
            print e 
            self.db.rollback() 
 
 
    @every(minutes=24 * 60) 
    def on_start(self): 
        self.crawl('https://www.v2ex.com/', callback=self.index_page, validate_cert=False) 
 
    @config(age=10 * 24 * 60 * 60) 
    def index_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/?tab="]').items(): 
            self.crawl(each.attr.href, callback=self.tab_page, validate_cert=False) 
 
 
    @config(age=10 * 24 * 60 * 60) 
    def tab_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/go/"]').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
 
 
    @config(age=10 * 24 * 60 * 60) 
    def board_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/t/"]').items(): 
            url = each.attr.href 
            if url.find('#reply')>0: 
                url = url[0:url.find('#')] 
            self.crawl(url, callback=self.detail_page, validate_cert=False) 
        for each in response.doc('a.page_normal').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
 
 
    @config(priority=2) 
    def detail_page(self, response): 
        title = response.doc('h1').text() 
        content = response.doc('p.topic_content').html().replace('"', '\\"') 
        self.add_question(title, content)  #插入数据库 
        return { 
            "url": response.url, 
            "title": title, 
            "content": content, 
        }
로그인 후 복사

以上就是Python爬虫实战之爬取 V2EX 网站帖子的内容,更多相关内容请关注PHP中文网(www.php.cn)!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿