استراتيجية بيثون لاستخراج النص من صفحات HTML المشوهة

StackOverflow https://stackoverflow.com/questions/1615072

سؤال

أحاول استخراج النص من صفحات HTML التعسفية. بعض الصفحات (التي ليس لدي سيطرة عليها) لديها HTML أو البرامج النصية التي تجعل هذا صعبًا. أنا أيضًا في بيئة استضافة مشتركة ، لذلك يمكنني تثبيت أي بيثون lib ، لكن لا يمكنني فقط تثبيت أي شيء أريده على الخادم.

لا يبدو أن pyparsing و html2text.py يعملان في صفحات HTML المشوهة.

مثال URL هو http://apnews.myway.com/article/20091015/d9bb7cgg1.html

عملي الحالي هو ما يلي تقريبًا:

# Try using BeautifulSoup 3.0.7a
soup = BeautifulSoup.BeautifulSoup(s) 
comments = soup.findAll(text=lambda text:isinstance(text,Comment))
[comment.extract() for comment in comments]
c=soup.findAll('script')
for i in c:
    i.extract()    
body = bsoup.body(text=True)
text = ''.join(body) 
# if BeautifulSoup  can't handle it, 
# alter html by trying to find 1st instance of  "<body" and replace everything prior to that, with "<html><head></head>"
# try beautifulsoup again with new html 

إذا كانت جميلة لا تزال لا تعمل ، فأنا ألجأ إلى استخدام مجريات في النظر إلى الشار الأول ، آخر شار (لمعرفة ما إذا كان يبدو أنه خط رمز # <؛ وأخذ عينة من الخط ثم تحقق مما إذا كانت الرموز الرموز هي كلمات أو أرقام إنجليزية. إذا كانت هناك عدد قليل من الرموز هي الكلمات أو الأرقام ، فأعتقد أن السطر هو رمز.

يمكنني استخدام التعلم الآلي لتفقد كل سطر ، لكن هذا يبدو مكلفًا بعض الشيء وربما يتعين علي تدريبه (لأنني لا أعرف الكثير عن آلات التعلم غير الخاضعة للإشراف) ، وبالطبع أكتبه أيضًا.

أي نصيحة ، أدوات ، استراتيجيات ستكون موضع ترحيب كبير. أدرك أيضًا أن الجزء الأخير من ذلك هو فوضوي إلى حد ما ، حيث إذا حصلت على سطر يحدد احتواء رمز ، فأنا حاليًا رمي الخط بأكمله حاليًا ، حتى لو كان هناك كمية صغيرة من النص الإنجليزي الفعلي في السطر.

هل كانت مفيدة؟

المحلول

حاول ألا تضحك ، ولكن:

class TextFormatter:
    def __init__(self,lynx='/usr/bin/lynx'):
        self.lynx = lynx

    def html2text(self, unicode_html_source):
        "Expects unicode; returns unicode"
        return Popen([self.lynx, 
                      '-assume-charset=UTF-8', 
                      '-display-charset=UTF-8', 
                      '-dump', 
                      '-stdin'], 
                      stdin=PIPE, 
                      stdout=PIPE).communicate(input=unicode_html_source.encode('utf-8'))[0].decode('utf-8')

أتمنى أن تكون قد حصلت على الوشق!

نصائح أخرى

حسنًا ، يعتمد ذلك على مدى جودة الحل. واجهت مشكلة مماثلة ، حيث استورد مئات صفحات HTML القديمة في موقع ويب جديد. لقد فعلت بشكل أساسي

# remove all that crap around the body and let BS fix the tags
newhtml = "<html><body>%s</body></html>" % (
    u''.join( unicode( tag ) for tag in BeautifulSoup( oldhtml ).body.contents ))
# use html2text to turn it into text
text = html2text( newhtml )

وقد نجح الأمر ، ولكن بالطبع قد تكون الوثائق سيئة للغاية لدرجة أن BS لا يمكن أن تنقذ كثيرًا.

سوف تقوم BeautifulSoup سيئة مع HTML المشوهة. ماذا عن بعض regex-fu؟

>>> import re
>>> 
>>> html = """<p>This is paragraph with a bunch of lines
... from a news story.</p>"""
>>> 
>>> pattern = re.compile('(?<=p>).+(?=</p)', re.DOTALL)
>>> pattern.search(html).group()
'This is paragraph with a bunch of lines\nfrom a news story.'

يمكنك بعد ذلك تجميع قائمة بالعلامات الصالحة التي تريد استخراج المعلومات منها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top