python 爬取伯樂線上完整版

來源:互聯網
上載者:User

標籤:span   tle   default   cep   meta   sys   sso   mysql   run   

在jobbole.py

import scrapyimport reimport datetimefrom urllib import parsefrom scrapy.http import Requestfrom ArticleSpider.items import JobBoleArticleItemfrom ArticleSpider.utils.common import get_md5from scrapy.loader import ItemLoaderclass JobboleSpider(scrapy.Spider):    name = ‘jobbole‘    allowed_domains = [‘blog.jobbole.com‘]    start_urls = [‘http://blog.jobbole.com/all-posts‘]    def parse(self, response):        """                1. 擷取文章列表頁中的文章url並交給scrapy下載後並進行解析                2. 擷取下一頁的url並交給scrapy進行下載, 下載完成後交給parse                """        # 解析列表頁中的所有文章url並交給scrapy下載後並進行解析        post_nodes = response.css("#archive .floated-thumb .post-thumb a")        for post_node in post_nodes:            #擷取封面圖的url            image_url = post_node.css("img::attr(src)").extract_first("")            post_url = post_node.css("::attr(href)").extract_first("")            #request下載完成之後,回調parse_detail進行文章詳情頁的解析            # Request(url=post_url,callback=self.parse_detail)            yield Request(url=parse.urljoin(response.url,post_url),meta={"front_image_url":image_url},callback=self.parse_detail)            #遇到href沒有網域名稱的解決方案            #response.url + post_url        # 提取下一頁並交給scrapy進行下載        next_url = response.css(".next.page-numbers::attr(href)").extract_first("")        if next_url:            yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse)    def parse_detail(self, response):        # front_image_url = response.meta.get("front_image_url", "")  #文章封面圖        # title = response.css(".entry-header h1::text").extract_first()        # create_date = response.css("p.entry-meta-hide-on-mobile::text").extract()[0].strip().replace("·","").strip()        # praise_nums = response.css(".vote-post-up h10::text").extract()[0]        # fav_nums = response.css(".bookmark-btn::text").extract()[0]        # match_re = re.match(".*?(\d+).*", fav_nums)        # if match_re:        #     fav_nums = int(match_re.group(1))        # else:        #     fav_nums = 0        #        # comment_nums = response.css("a[href=‘#article-comment‘] span::text").extract()[0]        # match_re = re.match(".*?(\d+).*", comment_nums)        # if match_re:        #     comment_nums = int(match_re.group(1))        # else:        #     comment_nums = 0        #        # # content = response.css("div.entry::text").extract()        # content = response.css(‘div.entry‘).extract_first()        #        # tag_list = response.css("p.entry-meta-hide-on-mobile a::text").extract()        # tag_list = [element for element in tag_list if not element.strip().endswith("評論")]        # tags = ",".join(tag_list)        # try:        #     create_date = datetime.datetime.strptime(create_date, "%Y/%m/%d").date()        # except Exception as e:        #     create_date = datetime.datetime.now().date()        # article_item = JobBoleArticleItem()        # article_item["title"] = title        # article_item["url"] = response.url        # article_item["create_date"] = create_date        # article_item["front_image_url"] = [front_image_url]        # article_item["praise_nums"] = praise_nums        # article_item["comment_nums"] = comment_nums        # article_item["fav_nums"] = fav_nums        # article_item["tags"] = tags        # article_item["content"] = content        # article_item["url_object_id"] = get_md5(response.url)        front_image_url = response.meta.get("front_image_url", "")  # 文章封面圖        item_loader = ItemLoader(item=JobBoleArticleItem(), response=response)        item_loader.add_css("title", ".entry-header h1::text")        item_loader.add_value("url", response.url)        item_loader.add_value("url_object_id", get_md5(response.url))        item_loader.add_css("create_date", "p.entry-meta-hide-on-mobile::text")        item_loader.add_value("front_image_url", [front_image_url])        item_loader.add_css("praise_nums", ".vote-post-up h10::text")        item_loader.add_css("comment_nums", "a[href=‘#article-comment‘] span::text")        item_loader.add_css("fav_nums", ".bookmark-btn::text")        item_loader.add_css("tags", "p.entry-meta-hide-on-mobile a::text")        item_loader.add_css("content", "div.entry")        #調用這個方法來對規則進行解析產生item對象        article_item = item_loader.load_item()        yield article_item

2.main.py

from scrapy.cmdline import executeimport sysimport ossys.path.append(os.path.dirname(os.path.abspath(__file__)))execute(["scrapy", "crawl", "jobbole"])

3.item.py

import scrapyimport datetimeimport refrom scrapy.loader import ItemLoaderfrom scrapy.loader.processors import MapCompose, TakeFirst, Joinclass ArticlespiderItem(scrapy.Item):    # define the fields for your item here like:    # name = scrapy.Field()    passdef date_convert(value):    try:        create_date = datetime.datetime.strptime(value, "%Y/%m/%d").date()    except Exception as e:        create_date = datetime.datetime.now().date()    return create_datedef get_nums(value):    match_re = re.match(".*?(\d+).*", value)    if match_re:        nums = int(match_re.group(1))    else:        nums = 0    return numsdef remove_comment_tags(value):    #去掉tag中提取的評論    if "評論" in value:        return ""    else:        return valuedef return_value(value):    return value# class JobBoleArticleItem(scrapy.Item):#     title = scrapy.Field()#     create_date = scrapy.Field()#     url = scrapy.Field()#     url_object_id = scrapy.Field()#     front_image_url = scrapy.Field()#     front_image_path = scrapy.Field()#     praise_nums = scrapy.Field()#     comment_nums = scrapy.Field()#     fav_nums = scrapy.Field()#     content = scrapy.Field()#     tags = scrapy.Field()class ArticleItemLoader(ItemLoader):    #自訂itemloader    default_output_processor = TakeFirst()class JobBoleArticleItem(scrapy.Item):    title = scrapy.Field()    create_date = scrapy.Field(        input_processor=MapCompose(date_convert),    )    url = scrapy.Field()    url_object_id = scrapy.Field()    front_image_url = scrapy.Field(        output_processor=MapCompose(return_value)    )    front_image_path = scrapy.Field()    praise_nums = scrapy.Field(        input_processor=MapCompose(get_nums)    )    comment_nums = scrapy.Field(        input_processor=MapCompose(get_nums)    )    fav_nums = scrapy.Field(        input_processor=MapCompose(get_nums)    )    #因為tag本身是list,所以要重寫    tags = scrapy.Field(        input_processor=MapCompose(remove_comment_tags),        output_processor=Join(",")    )    content = scrapy.Field()

4.pipelines.py

import codecsimport jsonimport MySQLdbimport MySQLdb.cursorsfrom twisted.enterprise import adbapifrom scrapy.pipelines.images import ImagesPipelinefrom scrapy.exporters import JsonItemExporterclass ArticlespiderPipeline(object):    def process_item(self, item, spider):        return itemclass ArticleImagePipeline(ImagesPipeline):    #重寫該方法可從result中擷取到圖片的實際    def item_completed(self, results, item, info):        for ok, value in results:            image_file_path = value["path"]        item["front_image_path"] = image_file_path        return itemclass MysqlTwistedPipline(object):    def __init__(self, dbpool):        self.dbpool = dbpool    @classmethod    def from_settings(cls, settings):        dbparms = dict(            host = settings["MYSQL_HOST"],            db = settings["MYSQL_DBNAME"],            user = settings["MYSQL_USER"],            passwd = settings["MYSQL_PASSWORD"],            charset=‘utf8‘,            cursorclass=MySQLdb.cursors.DictCursor,            use_unicode=True,        )        #**dbparms-->("MySQLdb",host=settings[‘MYSQL_HOST‘]        dbpool = adbapi.ConnectionPool("MySQLdb", **dbparms)        return cls(dbpool)    def process_item(self, item, spider):        #使用twisted將mysql插入變成非同步執行        query = self.dbpool.runInteraction(self.do_insert, item)        query.addErrback(self.handle_error, item, spider) #處理異常    def handle_error(self, failure, item, spider):        #處理非同步插入的異常        print (failure)    def do_insert(self, cursor, item):        #執行具體的插入        #根據不同的item 構建不同的sql語句並插入到mysql中        insert_sql, params = item.get_insert_sql()        cursor.execute(insert_sql, params)class JsonWithEncodingPipeline(object):    # 自訂json檔案的匯出    def __init__(self):        # 使用codecs開啟避免一些編碼問題。        self.file = codecs.open(‘article.json‘, ‘w‘, encoding="utf-8")    def process_item(self, item, spider):        # 將item轉換為dict,然後調用dumps方法產生json對象,false避免中文出錯        lines = json.dumps(dict(item), ensure_ascii=False) + "\n"        self.file.write(lines)        return item    # 當spider關閉的時候: 這是一個spider_closed的訊號量。    def spider_closed(self, spider):        self.file.close()class JsonExporterPipeline(object):    #調用scrapy提供的json export匯出json檔案    def __init__(self):        self.file = open(‘articleexport.json‘, ‘wb‘)        self.exporter = JsonItemExporter(self.file, encoding="utf-8", ensure_ascii=False)        self.exporter.start_exporting()    def  close_spider(self, spider):        self.exporter.finish_exporting()        self.file.close()    def process_item(self, item, spider):        self.exporter.export_item(item)        return itemclass MysqlPipeline(object):    #採用同步的機制寫入mysql    def __init__(self):        self.conn = MySQLdb.connect(‘localhost‘, ‘root‘, ‘123456‘, ‘article_spider‘, charset="utf8", use_unicode=True)        self.cursor = self.conn.cursor()    def process_item(self, item, spider):        insert_sql = """            insert into jobbole_article(title,create_date,url,url_object_id, front_image_url,praise_nums,comment_nums,fav_nums,tags,content)            VALUES (%s, %s, %s, %s, %s,%s,%s,%s,%s,%s)        """        self.cursor.execute(insert_sql, (item["title"],item["create_date"],item["url"],item["url_object_id"],item["front_image_url"],item["praise_nums"],item["comment_nums"],item["fav_nums"],item["tags"],item["content"]))        self.conn.commit()

  5.setting.py

import osBOT_NAME = ‘ArticleSpider‘SPIDER_MODULES = [‘ArticleSpider.spiders‘]NEWSPIDER_MODULE = ‘ArticleSpider.spiders‘# Crawl responsibly by identifying yourself (and your website) on the user-agent#USER_AGENT = ‘ArticleSpider (+http://www.yourdomain.com)‘# Obey robots.txt rulesROBOTSTXT_OBEY = False# Configure maximum concurrent requests performed by Scrapy (default: 16)#CONCURRENT_REQUESTS = 32# Configure a delay for requests for the same website (default: 0)# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay# See also autothrottle settings and docs#DOWNLOAD_DELAY = 3# The download delay setting will honor only one of:#CONCURRENT_REQUESTS_PER_DOMAIN = 16#CONCURRENT_REQUESTS_PER_IP = 16# Disable cookies (enabled by default)#COOKIES_ENABLED = False# Disable Telnet Console (enabled by default)#TELNETCONSOLE_ENABLED = False# Override the default request headers:#DEFAULT_REQUEST_HEADERS = {#   ‘Accept‘: ‘text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8‘,#   ‘Accept-Language‘: ‘en‘,#}# Enable or disable spider middlewares# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html#SPIDER_MIDDLEWARES = {#    ‘ArticleSpider.middlewares.ArticlespiderSpiderMiddleware‘: 543,#}# Enable or disable downloader middlewares# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#DOWNLOADER_MIDDLEWARES = {#    ‘ArticleSpider.middlewares.ArticlespiderDownloaderMiddleware‘: 543,#}# Enable or disable extensions# See https://doc.scrapy.org/en/latest/topics/extensions.html#EXTENSIONS = {#    ‘scrapy.extensions.telnet.TelnetConsole‘: None,#}# Configure item pipelines# See https://doc.scrapy.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES = {   ‘ArticleSpider.pipelines.ArticlespiderPipeline‘: 300,    # ‘scrapy.pipelines.images.ImagesPipeline‘: 1,    # ‘ArticleSpider.pipelines.ArticleImagePipeline‘:1,    ‘ArticleSpider.pipelines.JsonExporterPipeline‘:2,    # ‘ArticleSpider.pipelines.MysqlPipeline‘: 4,}IMAGES_URLS_FIELD = "front_image_url"project_dir = os.path.abspath(os.path.dirname(__file__))IMAGES_STORE = os.path.join(project_dir, ‘images‘)# Enable and configure the AutoThrottle extension (disabled by default)# See https://doc.scrapy.org/en/latest/topics/autothrottle.html#AUTOTHROTTLE_ENABLED = True# The initial download delay#AUTOTHROTTLE_START_DELAY = 5# The maximum download delay to be set in case of high latencies#AUTOTHROTTLE_MAX_DELAY = 60# The average number of requests Scrapy should be sending in parallel to# each remote server#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0# Enable showing throttling stats for every response received:#AUTOTHROTTLE_DEBUG = False# Enable and configure HTTP caching (disabled by default)# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings#HTTPCACHE_ENABLED = True#HTTPCACHE_EXPIRATION_SECS = 0#HTTPCACHE_DIR = ‘httpcache‘#HTTPCACHE_IGNORE_HTTP_CODES = []#HTTPCACHE_STORAGE = ‘scrapy.extensions.httpcache.FilesystemCacheStorage‘MYSQL_HOST = "localhost"MYSQL_DBNAME = "article_spider"MYSQL_USER = "root"MYSQL_PASSWORD = "123456"

  

  

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

python 爬取伯樂線上完整版

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.