目次
Pythonに基づくScrapy爬虫類入門:環境構築 PythonベースのScrapy爬虫類入門:ページ抽出 Pythonに基づくScrapy爬虫入門:画像処理次に、図虫網を例に画像をキャプチャする爬虫類プロジェクトを作成します.
一、内容分析
図虫网を开けて、上部のメニューの“発见”“ラベル”の中で各种のピクチャーに対する分类で、1つのラベルをクリックして、例えば“美人”、ホームページのリンクは:https://tuchong.com/tags/美女/、爬虫類の入り口として、このページを分析します.
ページを開くと、それぞれの図集が表示されます.図集をクリックすると、画面全体を閲覧できます.下にスクロールすると、ページ番号のページをめくる設定がなく、より多くの図集が表示されます.Chrome右クリック「要素をチェック」開発者ツールを開き、ページのソースコードをチェックします.内容部分は以下の通りです.
- , ,
li.gallery-item
, 。
Postman HTTP , :
, Ajax , div.widget-gallery
, XHR :
https://tuchong.com/rest/tags/ /posts?page=1&count=20&order=weekly&before_timestamp=
パラメータは です.pageはページ 、countはページごとの セット 、orderはソート、before_timestampは で、 はコンテンツ のサイトをプッシュするのでbefore_timestampは であるべきで、 なる は なる を します.ここでは、 を せずに のページから キャプチャします.
はJSON で、キャプチャの を げた. は の りである.{
"postList": [
{
"post_id": "15624611",
"type": "multi-photo",
"url": "https://weishexi.tuchong.com/15624611/",
"site_id": "443122",
"author_id": "443122",
"published_at": "2017-10-28 18:01:03",
"excerpt": "10 18 ",
"favorites": 4052,
"comments": 353,
"rewardable": true,
"parent_comments": "165",
"rewards": "2",
"views": 52709,
"title": " ",
"image_count": 15,
"images": [
{
"img_id": 11585752,
"user_id": 443122,
"title": "",
"excerpt": "",
"width": 5016,
"height": 3840
},
{
"img_id": 11585737,
"user_id": 443122,
"title": "",
"excerpt": "",
"width": 3840,
"height": 5760
},
...
],
"title_image": null,
"tags": [
{
"tag_id": 131,
"type": "subject",
"tag_name": " ",
"event_type": "",
"vote": ""
},
{
"tag_id": 564,
"type": "subject",
"tag_name": " ",
"event_type": "",
"vote": ""
}
],
"favorite_list_prefix": [],
"reward_list_prefix": [],
"comment_list_prefix": [],
"cover_image_src": "https://photo.tuchong.com/443122/g/11585752.webp",
"is_favorite": false
}
],
"siteList": {...},
"following": false,
"coverUrl": "https://photo.tuchong.com/443122/ft640/11585752.webp",
"tag_name": " ",
"tag_id": "564",
"url": "https://tuchong.com/tags/%E7%BE%8E%E5%A5%B3/",
"more": true,
"result": "SUCCESS"
}
によって、 する の がわかりやすくなります.ここでは、postlist
という に を つだけで、 する は であり、 にはいくつかの が です. -
url
: の で するページアドレス -
post_id
: は、ウェブサイトで であるべきであり、そのコンテンツ をキャプチャしたか かを するために することができる.-
site_id
: サイト 、 ソースリンクの には が されます.-
title
:タイトル -
excerpt
: -
type
: タイプ、 されている2 、1つのmulti-photo
は であり、1つのtext
は と が された ページであり、2つの が なり、 なるキャプチャ が であり、 では タイプのみをキャプチャし、textタイプは を する.-
tags
: ラベル、 の -
image_count
:ピクチャ -
images
:オブジェクト であるピクチャリスト. オブジェクトにimg_id
のプロパティを めるには が である.
ページの によると、 に のアドレスはこのようなフォーマットである:https://photo.tuchong.com/{site_id}/f/{img_id}.jpg
で、 の によって しやすい.
、プロジェクトの - cmderコマンドラインツールに り、
workon scrapy
を して に された に ります.このとき、コマンドラインプロンプトの に(Scrapy)
が され、この にあることを し、 するパスはPATH に され、 および が になります. -
scrapy startproject tuchong
tuchong - はプロジェクトのメインディレクトリに り、
scrapy genspider photo tuchong.com
を してphoto(プロジェクトと にできない)という を し、tuchongを する.comドメイン (これは が で、ここではまず のアドレスを します)、1つのプロジェクトに の を めることができます.
の を て、プロジェクトは にいくつかのファイルと を し、ディレクトリ は の りである.
(PROJECT)
│ scrapy.cfg
│
└─tuchong
│ items.py
│ middlewares.py
│ pipelines.py
│ settings.py
│ __init__.py
│
├─spiders
│ │ photo.py
│ │ __init__.py
│ │
│ └─__pycache__
│ __init__.cpython-36.pyc
│
└─__pycache__
settings.cpython-36.pyc
__init__.cpython-36.pyc
scrapy.cfg
: items.py
:エントリをキャプチャする middlewares.py
:ミドルウェア 、この ではを する はありません.
pipelines.py
:パイプ 、データをキャプチャするための .
settings.py
:グローバル spiders\photo.py
: 、 なデータをどのようにキャプチャするかを する 、 なコード
items.py
には、
TuchongItem
クラスが され、 な が されます. は、
scrapy.Field
の から されます. 、 、またはリスト、 などです.
import scrapy
class TuchongItem(scrapy.Item):
post_id = scrapy.Field()
site_id = scrapy.Field()
title = scrapy.Field()
type = scrapy.Field()
url = scrapy.Field()
image_count = scrapy.Field()
images = scrapy.Field()
tags = scrapy.Field()
excerpt = scrapy.Field()
...
これらのアトリビュートの は、 に えられます.
spiders\photo.py
このファイルはコマンド
scrapy genspider photo tuchong.com
によって に され、その は の りです.
import scrapy
class PhotoSpider(scrapy.Spider):
name = 'photo'
allowed_domains = ['tuchong.com']
start_urls = ['http://tuchong.com/']
def parse(self, response):
pass
name
、 されたドメイン
allowed_domains
(リンクがこのドメイン に さない は 、 )、 アドレス
start_urls
はここで するアドレスキャプチャ( )
parse
を を するデフォルトコールバック であり、パラメータ
response
は であり、ページ テキストは
response.body
に される.デフォルトのコードを ページのループ を たすように し する があります.これは
start_requests
を ロードし、ループ を じて ページのリンク を する があります. のコードは の りです.
import scrapy, json
from ..items import TuchongItem
class PhotoSpider(scrapy.Spider):
name = 'photo'
# allowed_domains = ['tuchong.com']
# start_urls = ['http://tuchong.com/']
def start_requests(self):
url = 'https://tuchong.com/rest/tags/%s/posts?page=%d&count=20&order=weekly';
# 10 , 20
# parse Requests
for page in range(1, 11):
yield scrapy.Request(url=url % (' ', page), callback=self.parse)
# , TuchongItem
def parse(self, response):
body = json.loads(response.body_as_unicode())
items = []
for post in body['postList']:
item = TuchongItem()
item['type'] = post['type']
item['post_id'] = post['post_id']
item['site_id'] = post['site_id']
item['title'] = post['title']
item['url'] = post['url']
item['excerpt'] = post['excerpt']
item['image_count'] = int(post['image_count'])
item['images'] = {}
# images {img_id: img_url}
for img in post.get('images', ''):
img_id = img['img_id']
url = 'https://photo.tuchong.com/%s/f/%s.jpg' % (item['site_id'], img_id)
item['images'][img_id] = url
item['tags'] = []
# tags tag_name
for tag in post.get('tags', ''):
item['tags'].append(tag['tag_name'])
items.append(item)
return items
これらの により、キャプチャされたデータは
TuchongItem
クラスに され、 されたデータとして および が になる.
したように、すべてのキャプチャされたエントリが とされるわけではありません. えば、この では
type="multi_photo
タイプの セットしか とせず、 が なすぎても ありません.これらのキャプチャされたエントリのフィルタリング と、
pipelines.py
で する が です.このファイルには、デフォルトで されたクラス
TuchongPipeline
がデフォルトであり、
process_item
が ロードされています.この を することで、 を たす
item
のみが されます.コードは のとおりです.
...
def process_item(self, item, spider):
# scrapy.exceptions.DropItem ,
if int(item['image_count']) < 3:
raise DropItem(" : " + item['url'])
elif item['type'] != 'multi-photo':
raise DropItem(" : " + + item['url'])
else:
print(item['url'])
return item
...
もちろん、パイプを わずに
parse
で するのも じですが、このような はもっとはっきりしていて、さらに くの
FilePipelines
と
ImagePipelines
が で、
process_item
は エントリをキャプチャした にトリガーされ、 に
open_spider
と
close_spider
の が ロードされ、 の の を することができます.
: はプロジェクトに して する があります.
settings.py
に します.
ITEM_PIPELINES = {
'tuchong.pipelines.TuchongPipeline': 300, # : ( )
}
また、 くのサイトには のRobotsがあります.txtはプロトコルを し、
ROBOTSTXT_OBEY = True
を してこれらのプロトコルを することができます.はい、これは のようです.ウェブサイトがブラウザのUser AgentあるいはIPアドレスを して に らって するならば、それでは に なScrapy が で、 は しません.
、
cmderコマンドラインを してプロジェクトディレクトリに り、コマンドを します.
scrapy crawl photo
はすべての とデバッグ を し、 に の をリストします.たとえば、 のようになります.
[scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 491,
'downloader/request_count': 2,
'downloader/request_method_count/GET': 2,
'downloader/response_bytes': 10224,
'downloader/response_count': 2,
'downloader/response_status_count/200': 2,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2017, 11, 27, 7, 20, 24, 414201),
'item_dropped_count': 5,
'item_dropped_reasons_count/DropItem': 5,
'item_scraped_count': 15,
'log_count/DEBUG': 18,
'log_count/INFO': 8,
'log_count/WARNING': 5,
'response_received_count': 2,
'scheduler/dequeued': 1,
'scheduler/dequeued/memory': 1,
'scheduler/enqueued': 1,
'scheduler/enqueued/memory': 1,
'start_time': datetime.datetime(2017, 11, 27, 7, 20, 23, 867300)}
に
ERROR
と
WARNING
の2つに し、ここでのWarningは は を たしていないことによってトリガーされた
DropItem
の である.
、 を する
ほとんどの 、キャプチャされた を する があります.デフォルトでは、
item.py
で された はファイルに できます.コマンドラインにパラメータ
-o {filename}
を するだけでいいです.
scrapy crawl photo -o output.json # JSON
scrapy crawl photo -o output.csv # CSV
:ファイルに される は、
TuchongPipeline
でフィルタされていない であり、
parse
で されるItemが される り、
parse
で な のみをフィルタリングして すこともできます.
データベースに する がある は、
pipelines.py
の
process_item
の に するなど、 のコード を する があります.
...
def process_item(self, item, spider):
...
else:
print(item['url'])
self.myblog.add_post(item) # myblog ,
return item
...
データベース で する を するために、
item['post_id']
を して し、 する はスキップすることができる.
プロジェクトのキャプチャ はテキストと リンクのみに し、 ファイルをダウンロードしていない. をダウンロードする がある は、2つの で うことができる.
は、Requests
モジュールをインストールし、process_item
でピクチャコンテンツをダウンロードするとともに、データベースの にローカルピクチャパスに き えます. ImagePipelines
パイプを して をダウンロードし、 な は します.