ホームページ >バックエンド開発 >Python チュートリアル >Python クローラーを最初から始めるためのクイックガイド
まえがき
この記事の主な内容: フォーラムの投稿タイトルと投稿コンテンツをクロールできる最も単純なクローラーを最短時間で作成します。
この記事の対象者: クローラーについて書いたことのない初心者。
はじめに
0. 準備する必要があるもの: Python、scrapy、IDE、または任意のテキスト編集ツール。
1. 技術部門が検討し、あなたがクローラーを書くことを決定しました。
任意に作業ディレクトリを作成し、コマンドラインを使用してプロジェクトを作成します。プロジェクト名はmiaoです。これは好きな名前に置き換えることができます。
scrapy startproject miaoすると、scrapyによって作成された以下のディレクトリ構造が得られます
クローラースクリプトとして、miao.pyなどのpythonファイルをspidersフォルダー内に作成します。内容は以下の通りです。
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
2. 試してみませんか?
コマンドラインを使用する場合は、次のようになります:
cd miao scrapy crawl NgaSpiderクローラーが星間領域の最初のページを出力したことがわかります。もちろん、何も処理されていないため、HTML タグとjs スクリプトを出力します。
次に、キャプチャしたページを分析し、この HTML と JS の山からこのページの投稿タイトルを抽出する必要があります。実際、ページの解析は面倒な作業なので、ここでは xpath のみを紹介します。
0. 魔法の xpath を試してみてはいかがでしょうか
先ほど取得したものを確認するか、Chrome ブラウザでページを手動で開き、F12 キーを押してページ構造を確認してください。各タイトルは実際にはこのような html タグで囲まれています。例:
<a href='/read.php?tid=10803874' id='t_tt1_33' class='topic'>[合作模式] 合作模式修改设想</a>href がこの投稿のアドレスであり (もちろんフォーラムのアドレスを先頭に入力する必要があります)、このタグで囲まれたコンテンツが投稿のタイトルであることがわかります。
そこで、xpathの絶対配置法を使ってclass='topic'の部分を抽出しました。
1. xpath の効果を見てください
先頭に引用符を追加します:
from scrapy import Selector解析関数を次のように変更します:
def parse(self, response): selector = Selector(response) # 在此,xpath会将所有class=topic的标签提取出来,当然这是个list # 这个list里的每一个元素都是我们要找的html标签 content_list = selector.xpath("//*[@class='topic']") # 遍历这个list,处理每一个标签 for content in content_list: # 此处解析标签,提取出我们需要的帖子标题。 topic = content.xpath('string(.)').extract_first() print topic # 此处提取出帖子的url地址。 url = self.host + content.xpath('@href').extract_first() print urlもう一度実行すると、すべての投稿のタイトルの出力が表示されます。フォーラムの星間エリアの最初のページと URL。
次に、各投稿のコンテンツをキャプチャする必要があります。ここではPythonのyieldを使用する必要があります。
yield Request(url=url, callback=self.parse_topic)ここでは、scrapy にこの URL をクロールし、指定された parse_topic 関数を使用してクロールされたページを解析するように指示します。 この時点で、投稿の内容を分析するための新しい関数を定義する必要があります。 完全なコードは次のとおりです:
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='topic']") for content in content_list: topic = content.xpath('string(.)').extract_first() print topic url = self.host + content.xpath('@href').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='postcontent ubbcode']") for content in content_list: content = content.xpath('string(.)').extract_first() print content # 可以在此处解析翻页信息,从而实现爬取帖子的多个页面これまでのところ、このクローラーはフォーラムの最初のページにあるすべての投稿のタイトルをクロールし、各投稿の最初のページの各フロアのコンテンツをクロールできます。複数のページをクロールする原理は同じですが、ページの URL アドレスの解析、終了条件の設定、および対応するページ解析関数の指定に注意してください。
ここでは、キャプチャおよび解析されたコンテンツの処理を示します。これらのコンテンツは、パイプラインを通じてローカル ファイルやデータベースに書き込むことができます。
0. アイテムを定義する
miao フォルダーに items.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 つの単純なクラスを定義します。
1. 処理メソッドを記述します
以前に Scrapy が自動生成されているはずの Pipelines.py ファイルを見つけます。
ここで処理メソッドを構築できます。class FilePipeline(object): ## 爬虫的分析结果都会由scrapy交给此函数处理 def process_item(self, item, spider): if isinstance(item, TopicItem): ## 在此可进行文件写入、数据库写入等操作 pass if isinstance(item, ContentItem): ## 在此可进行文件写入、数据库写入等操作 pass ## ... return item
2. クローラーでこの処理メソッドを呼び出します
。このメソッドを呼び出すには、クローラー内で呼び出すだけです。たとえば、元のコンテンツ処理関数を次のように変更できます。
def parse_topic(self, response): selector = Selector(response) content_list = selector.xpath("//*[@class='postcontent ubbcode']") for content in content_list: content = content.xpath('string(.)').extract_first() ## 以上是原内容 ## 创建个ContentItem对象把我们爬取的东西放进去 item = ContentItem() item["url"] = response.url item["content"] = content item["author"] = "" ## 略 ## 这样调用就可以了 ## scrapy会把这个item交给我们刚刚写的FilePipeline来处理 yield item
3. 設定ファイルでこのパイプラインを指定します。 py ファイルを開き、その中で見つけます
ITEM_PIPELINES = { 'miao.pipelines.FilePipeline': 400, }
を追加してクローラーで呼び出す
yield itemはこの FilePipeline によって処理されます。次の数字 400 は優先度を表します。
ここで複数のパイプラインを設定できます。Scrapy は優先度に従って順番にアイテムを各アイテムに渡し、各処理の結果は次のパイプラインに渡されて処理されます。
次のように複数のパイプラインを構成できます:ITEM_PIPELINES = { 'miao.pipelines.Pipeline00': 400, 'miao.pipelines.Pipeline01': 401, 'miao.pipelines.Pipeline02': 402, 'miao.pipelines.Pipeline03': 403, ## ... }
ミドルウェア - ミドルウェア
ミドルウェアを通じて、UA、プロキシ、ログインの一般的に使用される設定など、リクエスト情報にいくつかの変更を加えることができます。情報などはミドルウェアを通じて設定できます。 0. Middleware
の設定は、Setting.pyに
DOWNLOADER_MIDDLEWARES = { "miao.middleware.UserAgentMiddleware": 401, "miao.middleware.ProxyMiddleware": 402, }
1のように、UAを確認するためにWebサイトの名前を追加します。
某些网站不带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文件,填这个文件所在的目录。
示例:
按小绿箭头就可以愉快地调试了。