Dies ist der Befund, als die Ausführungsgeschwindigkeit von Image Search Bot mit BeautifulSoup verbessert wurde. Ich hoffe, es ist hilfreich für diejenigen, die in Schwierigkeiten sind, da die Ausführungsgeschwindigkeit des Scrapings langsam ist.
Sie können beschleunigen, indem Sie im Argument von BeautifulSoup einen geeigneten Zeichencode angeben: ** from_encoding **.
from urllib import request
import bs4
page = request.urlopen("https://news.yahoo.co.jp/")
html = page.read()
# from_Ersetzen Sie den Zeichencode der Site, die in die Codierung aufgenommen werden soll(Im Fall von Yahoo News diesmal utf-8)
soup = bs4.BeautifulSoup(html, "html.parser", from_encoding="utf-8")
Grundsätzlich wird es nach charset = in das Meta-Tag geschrieben.
<!--Im Fall von Yahoo News-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Ich habe es mit dem folgenden Skript überprüft. Gemessen vor und nach dem Erstellen einer Instanz
verification_bs4.py
from urllib import request as req
from urllib import parse
import bs4
import time
import copy
url = "https://news.yahoo.co.jp/"
page = req.urlopen(url)
html = page.read()
page.close()
start = time.time()
soup = bs4.BeautifulSoup(html, "html.parser")
print('{:.5f}'.format(time.time() - start) + "[s] html.parser, None")
start = time.time()
soup = bs4.BeautifulSoup(html, "lxml")
print('{:.5f}'.format(time.time() - start) + "[s] lxml, None")
start = time.time()
hoge = copy.copy(soup)
print('{:.5f}'.format(time.time() - start) + "[s] copy(lxml, None)")
start = time.time()
soup = bs4.BeautifulSoup(html, "html.parser", from_encoding="utf-8")
print('{:.5f}'.format(time.time() - start) + "[s] html.parser, utf-8")
start = time.time()
soup = bs4.BeautifulSoup(html, "lxml", from_encoding="utf-8")
print('{:.5f}'.format(time.time() - start) + "[s] lxml, utf-8")
start = time.time()
hoge = copy.copy(soup)
print('{:.5f}'.format(time.time() - start) + "[s] copy(lxml, utf-8)")
start = time.time()
soup = bs4.BeautifulSoup(html, "lxml", from_encoding="utf-16")
#Der Rückgabewert ist leer, da der Zeichencode unterschiedlich ist
print('{:.5f}'.format(time.time() - start) + "[s] lxml, utf-16")
Das Ausgabeergebnis ist hier.
% python verification_bs4.py
2.10937[s] html.parser, None
2.00081[s] lxml, None
0.04704[s] copy(lxml, None)
0.03124[s] html.parser, utf-8
0.03115[s] lxml, utf-8
0.04188[s] copy(lxml, utf-8)
0.01651[s] lxml, utf-16
Durch Angabe des Zeichencodes in ** from_encoding ** konnten wir die Instanziierung beschleunigen. Wenn ich mir den Code ansehe, der besagt, dass BeautifulSoup langsam ist, habe ich ihn nicht from_encoding zugewiesen, daher denke ich, dass dies die Ursache ist.
Ich habe mich gefragt, warum es solche Spezifikationen hat, also habe ich den Quellcode überprüft. Normalerweise berühre ich Python jedoch nicht so oft, sodass ich möglicherweise etwas schreibe, das nicht berücksichtigt wird. Der Quellcode ist hier
Wahrscheinlich aufgrund der in ** bs4 / dammit.py ** definierten Klasse ** EncodingDetector **. Das Folgende ist ein Teilcode-Auszug.
class EncodingDetector:
"""Suggests a number of possible encodings for a bytestring.
Order of precedence:
1. Encodings you specifically tell EncodingDetector to try first
(the override_encodings argument to the constructor).
2. An encoding declared within the bytestring itself, either in an
XML declaration (if the bytestring is to be interpreted as an XML
document), or in a <meta> tag (if the bytestring is to be
interpreted as an HTML document.)
3. An encoding detected through textual analysis by chardet,
cchardet, or a similar external library.
4. UTF-8.
5. Windows-1252.
"""
@property
def encodings(self):
"""Yield a number of encodings that might work for this markup.
:yield: A sequence of strings.
"""
tried = set()
for e in self.override_encodings:
if self._usable(e, tried):
yield e
# Did the document originally start with a byte-order mark
# that indicated its encoding?
if self._usable(self.sniffed_encoding, tried):
yield self.sniffed_encoding
# Look within the document for an XML or HTML encoding
# declaration.
if self.declared_encoding is None:
self.declared_encoding = self.find_declared_encoding(
self.markup, self.is_html)
if self._usable(self.declared_encoding, tried):
yield self.declared_encoding
# Use third-party character set detection to guess at the
# encoding.
if self.chardet_encoding is None:
self.chardet_encoding = chardet_dammit(self.markup)
if self._usable(self.chardet_encoding, tried):
yield self.chardet_encoding
# As a last-ditch effort, try utf-8 and windows-1252.
for e in ('utf-8', 'windows-1252'):
if self._usable(e, tried):
yield e
Wenn Sie den zu Beginn des Kurses geschriebenen Kommentar übersetzen, sieht er folgendermaßen aus (DeepL-Übersetzung)
""""Wir empfehlen einige mögliche Codierungen für Byte-Strings.
Die Reihenfolge der Priorität ist wie folgt.
1.Die Codierung, die Sie EncodingDetector angewiesen haben, zuerst zu versuchen
Konstruktorargument überschreiben_Codierungen verwenden).
2.Die im Bystestring selbst deklarierte Codierung.
XML-Deklaration(Wenn die Byte-Zeichenfolge als XML interpretiert wird)
Dokument), Oder<meta>Im Tag(Byte-Zeichenfolge
Als HTML-Dokument interpretiert)。
3.Die durch die Textanalyse von Charde erkannte Kodierung.
Verwenden Sie cchardet oder eine ähnliche externe Bibliothek.
4. 4.UTF-8。
5. Windows-1252。
"""
Aus den Kommentaren und der Verarbeitung schließe ich, dass es langsam ist, weil es verarbeitet wird, bis die obigen Listen 1 bis 5 in der richtigen Reihenfolge erfolgreich sind. Wenn Sie sich 2 ansehen, wird das Erraten des Zeichencodes aus dem zuvor erwähnten Meta-Tag ebenfalls automatisch durchgeführt. Ich denke, dass dies eine Überlegung ist, damit Sie es verwenden können, ohne den Zeichencode anzugeben, indem Sie sich die Quelle der Website ansehen. Beim Scraping denke ich jedoch, dass ich normalerweise den Quellcode überprüfe, daher denke ich nicht, dass es so spät sein sollte. (Wir haben nicht überprüft, welcher Prozess der Engpass ist. Bitte geben Sie mir jemanden.)
Im früheren Skript zur Messung der Ausführungszeit wird die Methode copy.copy () verwendet, um die Instanz zu duplizieren. Der Grund dafür, dass dies so schnell geschieht, liegt in \ _ \ _ copy \ _ \ _ von bs4 / __ init__.py. Das Folgende ist ein Teilcode-Auszug.
__init__.py
class BeautifulSoup(Tag):
def __copy__(self):
"""Copy a BeautifulSoup object by converting the document to a string and parsing it again."""
copy = type(self)(
self.encode('utf-8'), builder=self.builder, from_encoding='utf-8'
)
# Although we encoded the tree to UTF-8, that may not have
# been the encoding of the original markup. Set the copy's
# .original_encoding to reflect the original object's
# .original_encoding.
copy.original_encoding = self.original_encoding
return copy
Es ist schneller, weil ich mich hier für utf-8 entschieden habe. Im Gegenteil, wenn der Zeichencode der Scraping-Site nicht utf-8 ist, ist er langsamer. Im folgenden Messskript wird der Zeichencode mit price com von shift-jis gemessen.
verification_bs4_2.py
from urllib import request as req
from urllib import parse
import bs4
import time
import copy
url = "https://kakaku.com/"
page = req.urlopen(url)
html = page.read()
page.close()
start = time.time()
soup = bs4.BeautifulSoup(html, "html.parser")
print('{:.5f}'.format(time.time() - start) + "[s] html.parser, None")
start = time.time()
soup = bs4.BeautifulSoup(html, "lxml")
print('{:.5f}'.format(time.time() - start) + "[s] lxml, None")
start = time.time()
soup = bs4.BeautifulSoup(html, "lxml", from_encoding="shift_jis")
print('{:.5f}'.format(time.time() - start) + "[s] lxml, shift_jis")
start = time.time()
hoge = copy.copy(soup)
print('{:.5f}'.format(time.time() - start) + "[s] copy(lxml, shift_jis)")
Das Ausgabeergebnis ist hier.
% python verification_bs4_2.py
0.11084[s] html.parser, None
0.08563[s] lxml, None
0.08643[s] lxml, shift_jis
0.13631[s] copy(lxml, shift_jis)
Wie oben erwähnt, ist das Kopieren langsamer als utf-8. Im Fall von Shift-Jis hat sich die Ausführungsgeschwindigkeit jedoch kaum geändert, selbst wenn in ** from_encoding ** nichts angegeben ist. ~~ Ich weiß das nicht mehr </ font> ~~
Danke, dass Sie so weit gelesen haben! Am Ende tut es mir leid, dass es chaotisch wurde. Ich frage mich, warum mehr als 90% der Websites der Welt utf-8 sind, aber es ist langsam. Ich habe einen Artikel erstellt, weil ich der Meinung war, dass es ein Problem war, dass die Websites, die mit BeautifulSoup gesucht und ganz oben angekommen sind, dies nicht erwähnt haben. Wenn Sie es nützlich finden, wäre es ermutigend, wenn Sie "LGTM" könnten.
Referenz https://stackoverrun.com/ja/q/12619706
Recommended Posts