01 序文
前回の記事では、クローラーとは何か、クローラーが習得する必要があるいくつかの基本概念、クローラーが最初に習得したライブラリについて詳しく紹介しました。詳細については、ここをクリックしてください: クローラー (1) - をrequests
理解するクローラーの最も基本的なコンセプト、この記事1つで実践可能
次に、クローラに非常に必要なもう 1 つのツールである正規表現について詳しく説明します。
02 正規表現
定義: 正規表現は文字列を処理するための強力なツールであり、通常は特定のルールを満たすテキストを取得および置換するために使用されます。
2.1re
ライブラリ
Python は re ライブラリを通じて正規表現のサポートを提供しますが、正規表現を使用する前に、re モジュールをインポートしてモジュールの関数を呼び出す必要があります。
re のいくつかの共通パラメータ
re.I
: 大文字と小文字を無視して一致させますre.M
: 複数行のマッチングを許可しますre.S
: 改行を含むすべての文字に一致します
Python で正規表現を使用するには、通常、 re モジュールを使用する必要があります。一般的に使用される方法には次のようなものがあります。
-
re.search(pattern, string)
:正規表現に一致する文字列を検索します。最初の部分文字列を返し、一致する情報を含む Match オブジェクトを返します。一致するものが見つからない場合は None を返します。 -
re.findall(pattern, string)
:正規表現に一致する文字列を検索します。すべての部分文字列、それをリストとして返します。一致するものが見つからない場合は、空のリストが返されます。 -
re.sub(pattern, repl, string)
: 文字列内で正規表現に一致するすべての部分文字列を検索し、指定された文字列 repl に置き換えます。戻る置き換えられた文字列。
以下は行ごとに出力されるサンプルコードです。
import re
# 定义要匹配的正则表达式
pattern = r'^\d+\..*'
# 打开文件
with open('example.txt', 'r') as f:
# 按行读取文件内容
for line in f:
# 使用re.match()函数进行匹配
match_obj = re.match(pattern, line)
# 如果匹配成功,则输出该行内容
if match_obj:
print(line.strip())
上記のコードでは、照合する正規表現が最初に定義されており、数字で始まりその後に任意の文字が続く行と照合できます。次に、ファイルを開き、ファイルの内容を 1 行ずつ読み取り、 re.match() 関数を使用して各行の内容を照合します。一致した場合は、その行の内容を出力します。
strip()
この関数は文字列の両端のスペースと改行を削除できることに注意してください。
2.2 正規表現のパラメータ
よく使用される 2 つのパラメータ:
正規表現では、. と ? は両方とも特別な意味を持つメタ文字です。
- .一致を表します恣意的に単一文字 (改行を除く)。
たとえば、正規表現 ab は axb、a#b、ab などと一致します。
- ?前のものと一致することを表します部分式0回か1回。
たとえば、正規表現 ab?c は ac および abc に一致しますが、abbc には一致しません。
? を示すために他のメタ文字の後に使用することもできます。貪欲でないマッチング。たとえば、正規表現 a.*?b は ab、axxxb などと一致しますが、axxxbyyyb と一致する場合は、axxxb のみと一致します。
. と ? が上記の特別な意味を持つのは、正規表現のメタ文字として使用される場合のみであり、それら自体と一致する必要がある場合は、エスケープ文字 \ を使用する必要があります。たとえば、正規表現 ab は ab に一致しますが、axb、a#b などには一致しません。
2.2.1 一般的に使用されるメタキャラクター
コード | 説明する |
---|---|
。 | 改行を除く任意の文字に一致します |
\w | 文字、数字、アンダースコア、または漢字と一致します |
\s | 任意の空白に一致します |
\d | 数字を一致させる |
\b | 単語の先頭または末尾に一致します |
^ | 文字列の先頭と一致する |
$ | 文字列の末尾に一致します |
例:
-
^\d{8}$ は 8 桁の qq 番号と一致します。
-
\bOlive\b は、Olive という単語と一致します。
注: 私はオリバーとオリーブが大好きです。この時点では、\b...\b が一致する単語を返すため、オリバーではなくオリバーが返されます。
2.2.2 対義語
対義語文字: 主に、特定の文字を除く任意の文字を検索するために使用されます。
コード/構文 | 説明する |
---|---|
\W | 文字、数字、アンダースコア、または漢字以外の任意の文字と一致します |
\S | 空白以外の任意の文字に一致します |
\D | 数字以外の文字に一致します |
\B | 単語の先頭または末尾ではない位置に一致します |
[^x] | x を除く任意の文字に一致します |
[^データ] | データを除く任意の文字と一致します |
2.2.3 区切り文字
区切り文字: 区切り文字は、主に繰り返しの一致回数に使用されます。
コード/構文 | 説明する |
---|---|
* |
0 回以上繰り返します |
+ |
1回以上繰り返す |
? | 部分文字列が 0 回または 1 回繰り返される |
{n} | n回繰り返す |
{n,} | n回以上繰り返す |
{n,m} | n回からm回繰り返します |
2.2.4 エスケープ文字
エスケープ文字: \ を追加します。
例:メタキャラクターなど * \は\に変換する必要があります。 \* \\
文字分岐: 主に、さまざまな状況の選択に対応するために使用されます。さまざまな条件を区切るには、「|」を使用します。たとえば、固定電話の市外局番には、3 桁のものもあれば、4 桁のものもあります。このとき、文字の分岐を使用できます。
例: \d{3}-\d{8}|\d{4}-\d{8} は、2 つの異なる長さの市外局番を持つ固定電話と一致します。
2.2.5 文字のグループ化
文字のグループ化は、主に括弧 () を使用してグループ化することにより、複数の文字を繰り返すために使用されます。
形状は次のとおりです: (\d\w){3} 3 回繰り返し一致します (\d\w)
一般的なグループ化構文:
分類 | コード | 説明する |
---|---|---|
捕獲 | (経験値) | exp に一致し、テキストを自動名前付きグループにキャプチャします。 |
(?<名前>exp) | exp と一致し、テキストを name という名前のグループにキャプチャします。これは (?'name'exp) と書くこともできます。 | |
(?:exp) | exp に一致します。一致したテキストはキャプチャされません。また、このグループにグループ番号は割り当てられません。 | |
ゼロ幅アサーション | (?=exp) | exp の前の位置に一致させる |
(?<=exp) | exp の後の位置を一致させる | |
(?!経験値) | exp が後に続かない位置に一致します | |
(?<!exp) | exp が前にない位置に一致します | |
ノート | (?#コメント) | このタイプのグループ化は正規表現の処理には影響せず、人々が読むためのコメントを提供するために使用されます。 |
2.2.6 遅延マッチングと貪欲マッチング
貪欲なマッチング: 正規表現に繰り返しの修飾子が含まれている場合、通常の動作は次のようになります。できるだけ多く一致するのキャラクター。
遅延マッチング: 場合によっては、できるだけ少ない文字を一致させる必要があります。
例: a.*b は、a で始まり b で終わる最長の文字列と一致します。これを使用して aabab を検索すると、文字列 aabab 全体と一致します。ただし、現時点で照合する必要があるのは ab であるため、遅延照合を使用する必要があります。遅延マッチングでは、できるだけ少ない文字が一致します。
コード/構文 | 説明する |
---|---|
*? | 何度でも繰り返しますが、できるだけ少ない回数で行ってください |
+? | 1 回以上繰り返しますが、できるだけ少ない回数で行ってください。 |
?? | 0 回または 1 回繰り返しますが、できるだけ少ない回数にしてください |
{ん、む}? | n 回から m 回繰り返しますが、できるだけ少ない回数にしてください |
{ん、}? | あと n 回繰り返しますが、できる限り少なくしてください |
2.2.7 バックリファレンス
後方参照は、前のグループ化と一致するテキストを繰り返し検索するために使用されます。
括弧を使用して部分式を指定した後、部分式に一致するテキスト (つまり、このグループによってキャプチャされたコンテンツ) を式または他のプログラムでさらに処理できます。デフォルトでは、各グループには自動的にグループ番号が割り当てられます。
- デフォルトのグループ番号:
例: \b(\w+)\b\s+\1\b は、go go や kitty kitty などの繰り返しの単語と一致させるために使用できます。
この式は最初は単語、つまり単語の先頭と末尾の間に複数の文字または数字 (\b(\w+)\b) があり、この単語は番号 1 のグループにキャプチャされ、次に 1 つまたはさらに空白文字 (\s+)、最後にグループ 1 でキャプチャされたコンテンツ (つまり、前に一致した単語) (\1) が続きます。
- 自己指定: 部分式のグループ名を自分で指定することもできます。
部分式のグループ名を指定するには、次の構文を使用します: (?<Word>\w+) (または山括弧を ': (?'Word'\w+) に置き換えます)。そのため、put\w+ グループ名は次のように指定されます。言葉。欲しいこのグループがキャプチャしたものを後方参照するには、\k<Word> を使用できます。,所以上一个例子也可以写成这样:\b(?< Word>\w+)\b\s+\k< Word>\b
2.2.8 零宽断言
有时候需要查找某些匹配之前或之后的东西,这个时候就需要指定一个位置,这个位置应该满足一定的条件(即断言)。具体请看 本章的2.2.5
比如
\b\w+(?=ing\b)
,匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。
比如(?<=\bre)\w+\b
会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
2.3 常用的正则表达式
- 如果你自己实在学不会正则表达式,请点击这里,转载自其他大神:点击这里,他里面归纳了基本所有你想要的用的正则表达式。
- 如果里面没有你想要的,请私信我。
2.4 正则表达式的实例
(1) 抓取html里面的<title>
间的内容
#方法一
title = re.findall(r'<title>(.*?)</title>', content.decode('utf-8'))
# 方法二
pat = r'(?<=<title>).*?(?=</title>)'
ex = re.compile(pat, re.M|re.S)
obj = re.search(ex, content.decode('utf-8'))
title = obj.group()
print(title)
(2)爬取超链接<a>
标签间的内容
#获取完整超链接
res = r"<a.*?href=.*?<\/a>"
urls = re.findall(res, content.decode('utf-8'))
#获取超链接<a>和</a>之间内容
res = r'<a .*?>(.*?)</a>'
texts = re.findall(res, content.decode('utf-8'), re.S|re.M)
(3)抓取超链接标签的url
res = r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')"
urls = re.findall(res, content, re.I|re.S|re.M)
for url in urls:
print(url)
(4)抓取图片超链接标签的url
content = '''<img alt="Python" src="http://www.yangxiuzhang.com/eastmount.jpg" />'''
urls = re.findall('src="(.*?)"', content, re.I|re.S|re.M)
print urls
(5)获取url中最后一个参数
在使用Python爬取图片过程中,通常会遇到图片对应的url最后一个字段用来命名图片的情况,如“photo1.jpg”,需要通过解析url“/”后面的参数来获取图片。
urls = 'http://www..csdn.net/photo1.jpg'
name = urls.split('/')[-1]
print name
补充:如果取得的text有其他字符,可以进行数据的预处理
使用.replace()
方法,将需要替换的特殊字符统统替换成空字符,可以看数据分析这一讲,详细学习该方法的用法。
03 还在学习(ing)
想要学好爬虫,还需要学习以下基础知识:
- Beautiful Soup 4
- XPATH技术:分析网页的DOM树结构,通过XPATH技术定位网页所爬取内容的节点,再抓取数据
- Scrapy框架
- Selenium库