【问题标题】:Scraper fails to print all resultsScraper 无法打印所有结果
【发布时间】:2017-08-28 11:23:37
【问题描述】:

我用 python 编写了一个脚本来从 craigslist 中抓取五个项目的“姓名”和“电话”。我面临的问题是,当我运行我的脚本时,它只给出三个结果而不是五个结果。更具体地说,由于前两个链接在他们的页面中没有额外的链接(联系信息),所以他们不需要再次请求打开任何额外的页面。但是,没有(联系信息)链接的两个链接无法通过我的第二个函数中的“if ano_page_link:”语句渗透,并且永远不会被打印。如何修复这个漏洞,无论是否有电话号码,刮板都会打印所有五个结果。

我正在尝试的脚本:

import re ; import requests ; from lxml import html

base = "http://bangalore.craigslist.co.in"

url_list = [
'http://bangalore.craigslist.co.in/reb/d/flat-is-for-sale-at-cooke-town/6266183606.html',
'http://bangalore.craigslist.co.in/reb/d/prestige-sunnyside/6259128505.html',
'http://bangalore.craigslist.co.in/reb/d/jayanagar-2nd-block-4000-sft/6221720477.html',
'http://bangalore.craigslist.co.in/reb/d/prestige-ozone-type-3-r-villa/6259928614.html',
'http://bangalore.craigslist.co.in/reb/d/zed-homes-3-bedroom-flat-for/6257075793.html'
]

def get_link(medium_link):
    response = requests.get(medium_link).text
    tree = html.fromstring(response)
    try:
        name = tree.cssselect('span#titletextonly')[0].text
    except IndexError:
        name = ""
    try:
        link = base + tree.cssselect('a.showcontact')[0].attrib['href']
    except IndexError:
        link = ""
    parse_doc(name, link)

def parse_doc(title, ano_page_link):

    if ano_page_link:
        page = requests.get(ano_page_link).text            
        tel = re.findall(r'\d{10}', page)[0] if re.findall(r'\d{10}', page) else ""
        print(title, tel)

if __name__ == '__main__':
    for link in url_list:
        get_link(link)

我得到的结果:

Jayanagar 2nd Block, 4000 sft Plot for Sale 9845012673
PRESTIGE OZONE TYPE D 3 B/R VILLA FOR SALE 9611226364
T ZED HOMES 3 BEDROOM FLAT FOR SALE 9611226364

我期待的结果:

A Flat is for sale at  Cooke Town
Prestige Sunnyside
Jayanagar 2nd Block, 4000 sft Plot for Sale 9845012673
PRESTIGE OZONE TYPE D 3 B/R VILLA FOR SALE 9611226364
T ZED HOMES 3 BEDROOM FLAT FOR SALE 9611226364

【问题讨论】:

  • 您是否在for 循环中定义函数?为什么?
  • 对不起先生。我不应该有。我为这个演示做了这个。
  • 按照安德森先生的建议修改。

标签: python python-3.x web-scraping web-crawler


【解决方案1】:

请注意,例如,http://bangalore.craigslist.co.in/reb/d/flat-is-for-sale-at-cooke-town/6266183606.html 上没有与 'a.showcontact' 选择器匹配的链接,因此请遵循块

try:
    link = base + tree.cssselect('a.showcontact')[0].attrib['href']
except IndexError:
    link = ""

将返回link = ""

然后,当您调用 if ano_page_link: 时,if 块中的所有命令都将被忽略,因为条件 if ""False 并且什么都不会打印出来

您可以尝试以下方法:

def parse_doc(title, ano_page_link):

    if ano_page_link:
        page = requests.get(ano_page_link).text            
        tel = re.findall(r'\d{10}', page)[0] if re.findall(r'\d{10}', page) else ""
        print(title, tel)
    else:
        print(title)

【讨论】:

  • 感谢安德森爵士的回答。它解决了这个问题。我也想过“其他”块,但我的无知并没有让我这样做。大声笑!!。你是一个救生员。再次感谢先生。
  • 还有一件事要知道,先生。在正常情况下,在 csv 中写入数据时,我会将这一行放在打印语句“writer.writerow([title,tel])”之后或周围。但是,您能否建议我如何修改这一行,因为“标题”出现在这里两次(在打印语句中)。提前致谢。
  • 我不确定,因为我对.csv 有一点经验,但你可以试试if ano_page_link:...writer.writerow([title,tel])else: writer.writerow([title," "]) 之类的东西
  • 您的解决方案绝不会出错。它成功了。再次感谢先生。
【解决方案2】:

您可以通过将收集数据打印数据这两个任务分开来获得更大的灵活性。以后想要扩展时添加更多信息会更容易。

def collect_info(medium_link):
    response = requests.get(medium_link).text
    tree = html.fromstring(response)

    title = get_title(tree)
    contact_link = get_contact_link(tree)
    tel = get_tel(contact_link) if contact_link else ''

    return title, tel


def get_title(tree):
    try:
        name = tree.cssselect('span#titletextonly')[0].text
    except IndexError:
        name = ""
    return name

def get_contact_link(tree):
    try:
        link = base + tree.cssselect('a.showcontact')[0].attrib['href']
    except IndexError:
        link = ""
    return link

def get_tel(ano_page_link):
    page = requests.get(ano_page_link).text
    tel = re.findall(r'\d{10}', page)[0] if re.findall(r'\d{10}', page) else ""
    return tel

def print_info(title, tel):
    if tel:
        fmt = 'Title: {title}, Phone: {tel}'
    else:
        fmt = 'Title: {title}'
    print(fmt.format(title=title, tel=tel))

if __name__ == '__main__':
    for link in url_list:
        title, tel = collect_info(link)
        print_info(title, tel)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-13
    • 2016-03-02
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 2017-08-25
    • 2021-01-12
    相关资源
    最近更新 更多