在 python scraper 脚本中解析 facebook mobile 时出现 lxml 错误“IOError:读取文件时出错”

Posted

技术标签:

【中文标题】在 python scraper 脚本中解析 facebook mobile 时出现 lxml 错误“IOError:读取文件时出错”【英文标题】:lxml error "IOError: Error reading file" when parsing facebook mobile in a python scraper script 【发布时间】:2012-03-24 12:55:57 【问题描述】:

我使用来自Logging into facebook with python 帖子的修改脚本:

#!/usr/bin/python2 -u
# -*- coding: utf8 -*-

facebook_email = "YOUR_MAIL@DOMAIN.TLD"
facebook_passwd = "YOUR_PASSWORD"


import cookielib, urllib2, urllib, time, sys
from lxml import etree

jar = cookielib.CookieJar()
cookie = urllib2.HTTPCookieProcessor(jar)       
opener = urllib2.build_opener(cookie)

headers = 
    "User-Agent" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (Khtml, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7",
    "Accept" : "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,text/png,*/*;q=0.5",
    "Accept-Language" : "en-us,en;q=0.5",
    "Accept-Charset" : "utf-8",
    "Content-type": "application/x-www-form-urlencoded",
    "Host": "m.facebook.com"


try:
    params = urllib.urlencode('email':facebook_email,'pass':facebook_passwd,'login':'Log+In')
    req = urllib2.Request('http://m.facebook.com/login.php?m=m&refsrc=m.facebook.com%2F', params, headers)
    res = opener.open(req)
    html = res.read()

except urllib2.HTTPError, e:
    print e.msg
except urllib2.URLError, e:
    print e.reason[1]

def fetch(url):
    req = urllib2.Request(url,None,headers)
    res = opener.open(req)
    return res.read()

body = unicode(fetch("http://www.facebook.com/photo.php?fbid=404284859586659&set=a.355112834503862.104278.354259211255891&type=1"), errors='ignore')
tree = etree.parse(body)
r = tree.xpath('/see_prev')
print r.text

当我执行代码时,出现问题:

$ ./facebook_fetch_coms.py
Traceback (most recent call last):
  File "./facebook_fetch_coms_classic_test.py", line 42, in <module>
    tree = etree.parse(body)
  File "lxml.etree.pyx", line 2957, in lxml.etree.parse (src/lxml/lxml.etree.c:56230)
  File "parser.pxi", line 1533, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:82313)
  File "parser.pxi", line 1562, in lxml.etree._parseDocumentFromURL (src/lxml/lxml.etree.c:82606)
  File "parser.pxi", line 1462, in lxml.etree._parseDocFromFile (src/lxml/lxml.etree.c:81645)
  File "parser.pxi", line 1002, in lxml.etree._BaseParser._parseDocFromFile (src/lxml/lxml.etree.c:78554)
  File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74498)
  File "parser.pxi", line 650, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:75389)
  File "parser.pxi", line 588, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:74691)
IOError: Error reading file '<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Facebook</title><meta name="description" content="Facebook helps you connect and share with the people in your life."

目标是首先获取id=see_prevlxml 的链接,然后使用while 循环打开所有cmets,最终获取文件中的所有消息。任何帮助将不胜感激!

编辑: 我在 archlinux x86_64 和 lxml 2.3.3 上使用 Python 2.7.2。

【问题讨论】:

【参考方案1】:

这是你的问题:

tree = etree.parse(body)

documentation 表示“source 是包含 XML 数据的文件名或文件对象。”您提供了一个字符串,因此 lxml 将您的 HTTP 响应正文的文本作为您希望打开的文件的 name。不存在这样的文件,所以你会得到一个IOError

您收到的错误消息甚至说“读取文件时出错”,然后将您的 XML 字符串作为它尝试读取的文件的名称提供 这是一个关于正在发生的事情的重要提示。

您可能需要etree.XML(),它从字符串中获取输入。或者您可以直接使用tree = etree.parse(res) 将HTTP 请求读取到lxml(opener.open() 的结果是一个类似文件的对象,etree.parse() 应该非常乐意使用它)。

【讨论】:

我删除了 parse() 以支持 HTML() 并且效果更好,谢谢。

以上是关于在 python scraper 脚本中解析 facebook mobile 时出现 lxml 错误“IOError:读取文件时出错”的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 python cloudcraper 绕过 cloudflare

Python-Selenium table-scraper 只返回第一行

Python 中的 Scraper 给出“拒绝访问”

当试图从IOS应用商店解析数据时出现503错误。

iOS 上的 Pythonista URL Scraper

python Web Image Scraper