目次
スクレイピーフレームワーク
パイプライン-itrm-シェル
Scrapy のシミュレートされたログイン
スクレイピーのダウンロード画像
ミドルウェアのダウンロード
スクレイピーフレームワーク
意味:
構成:
実行中のプロセス: 1. Scrapy フレームワークは start_urls を取得し、リクエスト request を構築します。
2. リクエストはクローラーミドルウェアを通過してスクレイピーエンジンに送信され、エンジンはリクエストをスケジューラーに送信します(リクエストはキューに保存されます)。
3. 次に、スケジューラはリクエスト要求をエンジンに送信します。
4. 次に、エンジンは、中間のダウンロード ミドルウェアを通過して、リクエスト リクエストをダウンローダーに送信します。
5. ダウンローダーはインターネットにアクセスし、応答応答を返します。
6. ダウンローダーは取得したレスポンスをエンジンに送信し、途中でダウンロードミドルウェアを経由します。
7. エンジンは途中でクローラミドルウェアを通過し、応答をクローラに送信します。
8. クローラーはレスポンスを通じてデータを取得します (URL などを取得できます)。別のリクエストを送信する場合は、エンジンに送信するリクエストを作成し、それを一度再利用します。リクエストを送信しない場合は、 、クローラミドルウェアを経由してデータをエンジンに送信します。
9. エンジンはデータをパイプラインに送信します
10. 保存用のパイプライン
まず、cmd ページからプロジェクトを作成しましょう
c:/d:/e: --->ネットワークディスクの切り替え
cd ファイル名 --> ファイルに切り替えます
Scrapy startproject プロジェクト名 --------> プロジェクトの作成
Scrapy genspider クローラー ファイル名 ドメイン名 -------> クローラー ファイルを作成
スクレイピー クローラー クローラー ファイル名 ------------> クローラー ファイルを実行
また、クローラー ファイルを実行するための start.py ファイルを作成することもできます (プロジェクトの下に最初のレイヤーを作成するため)。
ファイルが作成された場所:
クローラー ファイルを実行するコード:
from scrapy import cmdline
# cmdline.execute("scrapy crawl baidu".split())
# cmdline.execute("scrapy crawl novel".split())
cmdline.execute("scrapy crawl shiping".split())
Scrapyインポートコマンドラインからインポート
cmdline.execute(['scrapy','crawl','クローラー ファイル名']) : クローラー ファイルを実行します
中のファイルを分析させてください
クローラー名.py ファイル
Scrapy フレームワークはいくつかのクラス属性を提供しており、これらのクラス属性の値は変更できることがわかりますが、def parse() は名前を変更したりパラメータを自由に渡すことはできません
settings.py ファイル
これを見つけて開き、コメントを削除します。値が小さいほど、最初に実行されます。開かないと、データを Pipelines.py ファイルに転送できません。
MyScrapyPipeline クラスの process_item() の item パラメーター
実演してみますと、
import scrapy
class BaiduSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['douban.com']
start_urls = ['https://movie.douban.com/review/best/']
def parse(self, response):
print(response.text)
結果:
最初の URL をクリックすると、次の URL にジャンプします。
これは、クローラー ファイルがルールに準拠しているためです。解決策は次のとおりです: settings.py ファイルで次のコードを見つけます。
True を False に変更して実行します
結果:
ミスが1つ減っているのがわかります
しかし、まだエラーが残っているので、以下で解決しましょう。
403 の解決策は、UA (ヘッダー要求ヘッダー) を追加することです。
ここで次のように見つけます。
My_scrapy (+http://www.yourdomain.com) をリクエスト ヘッダーに変更します。
結果:
普通にアクセスできる
middlewares.py ファイル (リクエストヘッダーの追加用)
しかし、これは面倒だと思う人もいるでしょう ヘッダーのリクエストヘッダーが頻繁に変更されると、非常に使いにくくなります この問題については、リクエストを送信する過程でリクエストヘッダーを追加すると、それほど面倒ではありません。もう、追加するにはどうすればよいですか?
小さなかわいい子は、ミドルウェアが使用できるかどうかを考えることができます。
次に、scrapy プロジェクト内の middlewares.py ファイルであるミドルウェアを見つけます。
このファイルを開くと、次の内容が表示されます。
主な理由は、このファイルがクローラー ミドルウェアとダウンロード ミドルウェアの両方を middlewares.py ファイルに書き込むことです。
MyScrapyDownloaderMiddleware これはダウンロードミドルウェアです
MyScrapySpiderMiddleware これはクローラーミドルウェアです
それでは、MyScrapyDownloaderMiddlewareについて説明しましょう
重要なのは、これら 2 つはより一般的に使用されるということです。process_crawler から始めましょう。
コードのスクリーンショット:
印刷すると印刷されないのですが、なぜこのようになるのでしょうか?ミドルウェアが開いていないことが原因ですので、設定ファイルとpyファイルを見つけてコメントを削除しましょう。
コードのスクリーンショット:
正常に実行されたら:
次に、process_response をもう一度試してみましょう
コードのスクリーンショット:
結果:
リクエストがレスポンスの前にあることがわかります
もしかしたら、いくつかの状況を考えたことがあるかもしれません。リクエストとレスポンスを作成できますか?
やってみよう
コードのスクリーンショット:
結果:
用心深い可愛い子は、それが期待していたものではないことに気づくでしょう。
以下では、ダウンロード ミドルウェアをインターセプトします。
これが問題です
以下について説明しましょう。
process_request(リクエスト、スパイダー)
# - return None: 処理を続行します。
return None の場合、このリクエストは渡されます。duoban の process_request() が return None を返すと、ダウンロード ミドルウェアの process_request() が実行されます
# - または return 時に Request オブジェクトを返します
(Request オブジェクト)デュオバンの process_request() は return (Request オブジェクト) を返します。ダウンロード ミドルウェアの process_request() は実行されずにエンジンに戻り、エンジンはスケジューラに戻ります (同様に戻ります)。 way) # -
or return a Response オブジェクトは
return (Response オブジェクト) のときに渡されません。たとえば、duoban の process_request() が return (Response オブジェクト) を返す場合、ダウンロード ミドルウェアの process_request() は実行されずに戻ります。エンジンに送信され、エンジンはクローラー ファイル (クロスレベル) に戻ります。
# - または、IgnoreRequest: process_Exception() メソッドを発生させます。このメソッドが例外をスローした場合、process_Exception メソッドが呼び出されます。
# インストールされているダウンローダー ミドルウェアが呼び出されます。
process_response(リクエスト、レスポンス、スパイダー)
# - Response オブジェクトを返す
# - Request オブジェクトを返す Request
オブジェクトを返す: 仲介者呼び出しを停止し、それをスケジューラに入れてダウンロードをスケジュールする;
# - または IgnoreRequest を発生させる
リクエスト ヘッダーを追加するミドルウェアを自分で作成できないか、と考える人もいるでしょう: ( middlewares.py ファイル内)
from scrapy import signals
import random
class UsertMiddleware:
User_Agent=["Mozilla/5.0 (compatible; MSIE 9.0; AOL 9.7; AOLBuild 4343.19; Windows NT 6.1; WOW64; Trident/5.0; FunWebProducts)",
"Mozilla/4.0 (compatible; MSIE 8.0; AOL 9.7; AOLBuild 4343.27; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"]
def process_request(self, request, spider):
# 添加请求头
print(dir(request))
request.headers["User-Agent"]=random.choice(self.User_Agent)
# 添加代理ip
# request.meta["proxies"]="代理ip"
return None
class UafgfMiddleware:
def process_response(self, request, response, spider):
# 检测请求头是否添加上
print(request.headers["User-Agent"])
return response
結果
実行可能です
Pipelines.py ファイル
process_item(自分、アイテム、スパイダー)
item: クローラー ファイルによって返されたデータ (辞書など) を受信します。
豆板まで這いましょう
Douban の映画の写真をクロールする練習をする
クローラー ファイル.py:
import scrapy
class BaiduSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['douban.com','doubanio.com']
start_urls = ['https://movie.douban.com/review/best/']
a=1
def parse(self, response):
divs=response.xpath('//div[@id="content"]//div[@class="review-list chart "]//div[@class="main review-item"]')
for div in divs:
# print(div.extract)
title=div.xpath('./a/img/@title')
src=div.xpath('./a/img/@src')
# print(title.extract_first())
print(src.extract_first())
yield {
"title": title.extract_first(),
"src": src.extract_first(),
"type": "csv"
}
# 再发请求下载图片
yield scrapy.Request(
url=src.extract_first(),
callback=self.parse_url,
cb_kwargs={"imgg":title.extract_first()}
)
#第一种
# next1=response.xpath(f'//div[@class="paginator"]//a[1]/@href').extract_first()
# 第二种方法自己构建
next1="/review/best?start={}".format(20*self.a)
self.a+=1
url11='https://movie.douban.com'+next1
yield scrapy.Request(url=url11,callback=self.parse)
print(url11)
def parse_url(self,response,imgg):
# print(response.body)
yield {
"title":imgg,
"ts":response.body,
"type":"img"
}
Pipelines.py ファイル:
import csv
class MyScrapyPipeline:
def open_spider(self,spider): # 当爬虫开启时调用
header = ["title", "src"]
self.f = open("move.csv", "a", encoding="utf-8")
self.wri_t=csv.DictWriter(self.f,header)
self.wri_t.writeheader()
def process_item(self, item, spider): # 每次传参都会调用一次
if item.get("type")=="csv":
item.pop("type")
self.wri_t.writerow(item)
if item.get("type")=="img":
item.pop("type")
with open("./图片/{}.png".format(item.get("title")),"wb")as f:
f.write(item.get("ts"))
print("{}.png下载完毕".format(item.get("title")))
return item
def close_spider(self,spider):
self.f.close()
settings.py ファイル:
これは出力したいものだけを出力できます
________________________________________________
上記はすべてオープンです
クローラー ファイル内の送信リクエストが失敗した場合、pipelines.py ファイル内の関数をコールバックすることはできないことに注意してください。
クローラーを一時停止および再開する方法
クローラーを一時停止したり再開したりする方法があると考えている人もいますか? もしそうなら、それは何ですか?
それについて話しましょう
Scrapy クローラー クローラー ファイル名 -s JOBDIR=ファイル パス (定義するだけ)
Ctrl+C でクローラーを一時停止します
かわいい子がもう一度復元しようとすると、ダウンロードを実行できないことがわかります。
なぜかというと、フレームワークで与えられたメソッドと記述したメソッドが違うので、
Scrapy.Request は次のとおりです。
dont_filte (フィルタリングしない?) r はフィルタです。False の場合はフィルタリングされます (同じ URL は 1 回しかアクセスされません)、True の場合はフィルタリングされません
かわい子ちゃんは、なぜ parse() が送信できるのか考えてみると、結果は次のようになります。
結果は非常に明確です。フィルタをかけたくない場合は、変更する必要があります。
オーバーライドされたメソッドをフィルタリングする場合は、次のようにします。
Scrapy のシミュレートされたログイン
次の 2 つの方法があります。
● 1 Cookie を直接実行してページをリクエストします (半自動的に、Selenium を使用して Cookie を取得するか、手動で Cookie を取得します)。
https://www.1905.com/vod/list/c_178/o3u1p1.html主張するには
1つ目の方法は手動ログインで取得したリクエストページです。
クローラー ファイルのコード例 1 (クローラー ファイルに Cookie を追加);
import scrapy
class A17kSpider(scrapy.Spider):
name = '17k'
allowed_domains = ['17k.com']
start_urls = ['https://www.17k.com/']
# 重写
def start_requests(self):
cook="GUID=f0f80f5e-fb00-443f-a6be-38c6ce3d4c61; __bid_n=1883d51d69d6577cf44207; BAIDU_SSP_lcr=https://www.baidu.com/link?url=v-ynoaTMtiyBil1uTWfIiCbXMGVZKqm4MOt5_xZD0q7&wd=&eqid=da8d6ae20003f26f00000006647c3209; Hm_lvt_9793f42b498361373512340937deb2a0=1684655954,1684929837,1685860878; dfxafjs=js/dfxaf3-ef0075bd.js; FPTOKEN=zLc3s/mq2pguVT/CfivS7tOMcBA63ZrOyecsnTPMLcC/fBEIx0PuIlU5HgkDa8ETJkZYoDJOSFkTHaz1w8sSFlmsRLKFG8s+GO+kqSXuTBgG98q9LQ+EJfeSHMvwMcXHd+EzQzhAxj1L9EnJuEV2pN0w7jUCYmfORSbIqRtu5kruBMV58TagSkmIywEluK5JC6FnxCXUO0ErYyN/7awzxZqyqrFaOaVWZZbYUrhCFq0N8OQ1NMPDvUNvXNDjDOLM6AU9f+eHsXFeAaE9QunHk6DLbxOb8xHIDot4Pau4MNllrBv8cHFtm2U3PHX4f6HFkEpfZXB0yVrzbX1+oGoscbt+195MLZu478g3IFYqkrB8b42ILL4iPHtj6M/MUbPcxoD25cMZiDI1R0TSYNmRIA==|U8iJ37fGc7sL3FohNPBpgau0+kHrBi2OlH2bHfhFOPQ=|10|87db5f81d4152bd8bebb5007a0f3dbc3; c_channel=0; c_csc=web; accessToken=avatarUrl%3Dhttps%253A%252F%252Fcdn.static.17k.com%252Fuser%252Favatar%252F03%252F43%252F75%252F100257543.jpg-88x88%253Fv%253D1685860834000%26id%3D100257543%26nickname%3D%25E8%2580%2581%25E5%25A4%25A7%25E5%2592%258C%25E5%258F%258D%25E5%25AF%25B9%25E6%25B3%2595%25E7%259A%2584%25E5%258F%258D%26e%3D1701413546%26s%3Db67793dfa5cea859; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22100257543%22%2C%22%24device_id%22%3A%221883d51d52d1790-08af8c489ac963-26031a51-1638720-1883d51d52eea0%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%7D%2C%22first_id%22%3A%22f0f80f5e-fb00-443f-a6be-38c6ce3d4c61%22%7D; Hm_lpvt_9793f42b498361373512340937deb2a0=1685861547"
yield scrapy.Request(
url=self.start_urls[0],
callback=self.parse,
cookies={lis.split("=")[0]:lis.split("=")[1] for lis in cook.split(";")}
)
def parse(self, response):
# print(response.text)
yield scrapy.Request(url="https://user.17k.com/www/",callback=self.parse_url)
def parse_url(self,response):
print(response.text)
結果:
クローラー ファイルのコード例 2 (ミドルウェア ファイルをダウンロードするための Cookie を追加);
class MyaddcookieMiddleware:
def process_request(self, request, spider):
cook = "GUID=f0f80f5e-fb00-443f-a6be-38c6ce3d4c61; __bid_n=1883d51d69d6577cf44207; BAIDU_SSP_lcr=https://www.baidu.com/link?url=v-ynoaTMtiyBil1uTWfIiCbXMGVZKqm4MOt5_xZD0q7&wd=&eqid=da8d6ae20003f26f00000006647c3209; Hm_lvt_9793f42b498361373512340937deb2a0=1684655954,1684929837,1685860878; dfxafjs=js/dfxaf3-ef0075bd.js; FPTOKEN=zLc3s/mq2pguVT/CfivS7tOMcBA63ZrOyecsnTPMLcC/fBEIx0PuIlU5HgkDa8ETJkZYoDJOSFkTHaz1w8sSFlmsRLKFG8s+GO+kqSXuTBgG98q9LQ+EJfeSHMvwMcXHd+EzQzhAxj1L9EnJuEV2pN0w7jUCYmfORSbIqRtu5kruBMV58TagSkmIywEluK5JC6FnxCXUO0ErYyN/7awzxZqyqrFaOaVWZZbYUrhCFq0N8OQ1NMPDvUNvXNDjDOLM6AU9f+eHsXFeAaE9QunHk6DLbxOb8xHIDot4Pau4MNllrBv8cHFtm2U3PHX4f6HFkEpfZXB0yVrzbX1+oGoscbt+195MLZu478g3IFYqkrB8b42ILL4iPHtj6M/MUbPcxoD25cMZiDI1R0TSYNmRIA==|U8iJ37fGc7sL3FohNPBpgau0+kHrBi2OlH2bHfhFOPQ=|10|87db5f81d4152bd8bebb5007a0f3dbc3; c_channel=0; c_csc=web; accessToken=avatarUrl%3Dhttps%253A%252F%252Fcdn.static.17k.com%252Fuser%252Favatar%252F03%252F43%252F75%252F100257543.jpg-88x88%253Fv%253D1685860834000%26id%3D100257543%26nickname%3D%25E8%2580%2581%25E5%25A4%25A7%25E5%2592%258C%25E5%258F%258D%25E5%25AF%25B9%25E6%25B3%2595%25E7%259A%2584%25E5%258F%258D%26e%3D1701413546%26s%3Db67793dfa5cea859; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22100257543%22%2C%22%24device_id%22%3A%221883d51d52d1790-08af8c489ac963-26031a51-1638720-1883d51d52eea0%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%7D%2C%22first_id%22%3A%22f0f80f5e-fb00-443f-a6be-38c6ce3d4c61%22%7D; Hm_lpvt_9793f42b498361373512340937deb2a0=1685861547"
cookies = {lis.split("=")[0]: lis.split("=")[1] for lis in cook.split(";")}
request.cookies=cookies
return None
クローラー ファイルのコード例 3 (ミドルウェア ファイルをダウンロードするために Cookie を追加);
def sele():
#创建一个浏览器
driver=webdriver.Chrome()
#打开网页
driver.get("https://user.17k.com/www/bookshelf/")
print("你有15秒的时间登入")
time.sleep(15)
print(driver.get_cookies())
print({i.get("name"):i.get("value") for i in driver.get_cookies()})
class MyaddcookieMiddleware:
def process_request(self, request, spider):
sele()
return None
Cookie を保存するための投稿リクエストを送信するインターフェイスを見つける
コード 1:
import scrapy
class A17kSpider(scrapy.Spider):
name = '17k'
allowed_domains = ['17k.com']
start_urls = ['https://www.17k.com/']
# # 重写
# def start_requests(self):
# cook="GUID=f0f80f5e-fb00-443f-a6be-38c6ce3d4c61; __bid_n=1883d51d69d6577cf44207; BAIDU_SSP_lcr=https://www.baidu.com/link?url=v-ynoaTMtiyBil1uTWfIiCbXMGVZKqm4MOt5_xZD0q7&wd=&eqid=da8d6ae20003f26f00000006647c3209; Hm_lvt_9793f42b498361373512340937deb2a0=1684655954,1684929837,1685860878; dfxafjs=js/dfxaf3-ef0075bd.js; FPTOKEN=zLc3s/mq2pguVT/CfivS7tOMcBA63ZrOyecsnTPMLcC/fBEIx0PuIlU5HgkDa8ETJkZYoDJOSFkTHaz1w8sSFlmsRLKFG8s+GO+kqSXuTBgG98q9LQ+EJfeSHMvwMcXHd+EzQzhAxj1L9EnJuEV2pN0w7jUCYmfORSbIqRtu5kruBMV58TagSkmIywEluK5JC6FnxCXUO0ErYyN/7awzxZqyqrFaOaVWZZbYUrhCFq0N8OQ1NMPDvUNvXNDjDOLM6AU9f+eHsXFeAaE9QunHk6DLbxOb8xHIDot4Pau4MNllrBv8cHFtm2U3PHX4f6HFkEpfZXB0yVrzbX1+oGoscbt+195MLZu478g3IFYqkrB8b42ILL4iPHtj6M/MUbPcxoD25cMZiDI1R0TSYNmRIA==|U8iJ37fGc7sL3FohNPBpgau0+kHrBi2OlH2bHfhFOPQ=|10|87db5f81d4152bd8bebb5007a0f3dbc3; c_channel=0; c_csc=web; accessToken=avatarUrl%3Dhttps%253A%252F%252Fcdn.static.17k.com%252Fuser%252Favatar%252F03%252F43%252F75%252F100257543.jpg-88x88%253Fv%253D1685860834000%26id%3D100257543%26nickname%3D%25E8%2580%2581%25E5%25A4%25A7%25E5%2592%258C%25E5%258F%258D%25E5%25AF%25B9%25E6%25B3%2595%25E7%259A%2584%25E5%258F%258D%26e%3D1701413546%26s%3Db67793dfa5cea859; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22100257543%22%2C%22%24device_id%22%3A%221883d51d52d1790-08af8c489ac963-26031a51-1638720-1883d51d52eea0%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%7D%2C%22first_id%22%3A%22f0f80f5e-fb00-443f-a6be-38c6ce3d4c61%22%7D; Hm_lpvt_9793f42b498361373512340937deb2a0=1685861547"
# yield scrapy.Request(
# url=self.start_urls[0],
# callback=self.parse,
# cookies={lis.split("=")[0]:lis.split("=")[1] for lis in cook.split(";")}
# )
#
# def parse(self, response):
# # print(response.text)
# # yield scrapy.Request(url="https://user.17k.com/www/bookshelf/",callback=self.parse_url)
# pass
# def parse_url(self,response):
#
# # print(response.text)
# pass
#发送post请求
def parse(self, response):
data={
"loginName": "15278307585",
"password": "wasd1234"
}
yield scrapy.FormRequest(
url="https://passport.17k.com/ck/user/login",
callback=self.prase_url,
formdata=data
)
#适用于该页面有form表单
# yield scrapy.FormRequest.from_response(response,formdata=data,callback=self.start_urls)
def prase_url(self,response):
print(response.text)
これらに加えて、ミドルウェアをダウンロードすることで応答オブジェクトを返すことができます
from scrapy import signals
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
from scrapy.http.response.html import HtmlResponse
lass MyaaacookieMiddleware:
def process_request(self, request, spider):
# 创建一个浏览器
driver=webdriver.Chrome()
# 打开浏览器
driver.get("https://juejin.cn/")
driver.implicitly_wait(3)
# js语句下拉
for i in range(3):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
time.sleep(3)
html=driver.page_source
return HtmlResponse(url=driver.current_url,body=html,request=request,encoding="utf-8")
以上です。
要約する
Scrapy フレームワークは、大量のデータのクロールによって引き起こされる大量のコードの書き換えを解決し、少量のコードで問題を解決することです。