网页肯定有40行数据,为什么只能获取部分行?

问题描述 投票:0回答:2

webapi "vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/profit/index.phtml" ,提供

get
方法调用的query,每页40行分页。 我写了一个函数来调用 webapi 并打印网页中的所有行:

def get_rows(page):
    import urllib.request
    import lxml.html
    url = "http://vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/profit/"\
          "index.phtml?s_i=&s_a=&s_c=&reportdate=2021&quarter=4&p={}".format(page)
    table_xpath = '//*[@id="dataTable"]'
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    req = urllib.request.Request(url=url, headers=headers)
    data_string=urllib.request.urlopen(req).read()
    root=lxml.html.fromstring(data_string)
    dtable = root.xpath(table_xpath)[0]
    rows = dtable.xpath('.//tr')
    print(len(rows))

现在称它为:

get_rows(page=1)
41
get_rows(page=2)
41
get_rows(page=3)
26
get_rows(page=4)
41

为什么当网页确实包含40行(41=1个标题+40行数据)时,我的函数只能获取第3页的部分行(26)? 我发现很多页面都遇到了同样的问题,wbeoage 包含 40 行数据,get_rows() 打印的数字小于 40。请尝试使用我的函数:

[get_rows(page) for page in [3,38,73,81,118,123]]
python-3.x web-crawler
2个回答
0
投票

问题似乎是股票代码 688279(峰岩科技)对应的股票名称在编码为 GB 2312 时生成无效的 UTF-8 字节。

在您调用的代码中:

urllib.request.urlopen(req).read()

这将返回响应的原始字节。大概在里面的某个地方:

lxml.html.fromstring(data_string)

对正确编码的猜测不正确,当发现无效字符时,处理似乎只是停止。

最好的前进路径似乎是 here 中概述的路径,它使用作为 HTTP 响应的一部分返回的字符集编码对读取的字节进行解码,而不是推迟到

lxml
来确定字符编码。因此,在这种特殊情况下,这涉及更改:

data_string=urllib.request.urlopen(req).read()

类似的东西:

resource=urllib.request.urlopen(req)
data_string=resource.read().decode(resource.headers.get_content_charset())

0
投票

目标网页中的编码是

gb2312
,但是如果你使用它,会出现无效编码错误,尝试了很多次,最后设置
gbk
就可以了!

def get_rows(page):
    import urllib.request
    import lxml.html
    url = "http://vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/profit/"\
          "index.phtml?s_i=&s_a=&s_c=&reportdate=2021&quarter=4&p={}".format(page)
    table_xpath = '//*[@id="dataTable"]'
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    req = urllib.request.Request(url=url, headers=headers)
    data_string=urllib.request.urlopen(req).read().decode('gbk')
    root=lxml.html.fromstring(data_string)
    dtable = root.xpath(table_xpath)[0]
    rows = dtable.xpath('.//tr')
    print(len(rows))
© www.soinside.com 2019 - 2024. All rights reserved.