【问题标题】:Scan URLs in CSV file and add column TRUE/FALSE once websites are active/not active扫描 CSV 文件中的 URL 并在网站处于活动/非活动状态时添加 TRUE/FALSE 列
【发布时间】:2020-06-30 21:48:49
【问题描述】:

我是 python 新手,目前正试图找到一种方法来扫描我的 CSV 文件中的所有 URL,以查找网站是否显示了特定的字符串(在我的情况下,我需要检查多个字符串:'不可用”、“即将推出”和“暂时关闭”)。

CSV 文件结构:

id    website
1    https://www.rainfordsolutions.com/new-online-shop-coming-soon
2    https://www.arrey-fashion.com/a-nice-entry/
3    https://google.com
...

我认为我首先需要对我的网站 URL 进行某种循环,然后为每个网站创建另一个循环以查看我要查找的关键字是否存在,最后将结果写入我的 CSV 文件,其中:如果没有找到关键字(网站有效),则为 TRUE,如果找到我的任何关键字(网站无效),则为 FALSE。我不确定如何解决这个问题。我从 pandas 和 urllib.request 开始,但我知道还有漂亮的汤和请求库。有人可以帮我解决这个问题吗?提前致谢!

import pandas as pd
import urllib.request

df = pd.read_csv('path/to/my/file/with/urls.csv')
for v in df['website']:
with urllib.request.urlopen(v) as url:


df['active'] = 

df.to_csv('path/to/my/output/urls_and_flag.csv', index=False)

所需的输出 urls_and_flag.cs​​v:

id    website                                                           active
1    https://www.rainfordsolutions.com/new-online-shop-coming-soon      FALSE
2    https://www.arrey-fashion.com/a-nice-entry/                        FALSE
3    https://google.com                                                 TRUE
...

【问题讨论】:

    标签: python pandas csv web-scraping beautifulsoup


    【解决方案1】:

    您可以使用类似asyncio 的方式异步执行函数并等待结果。在您的函数中使用 来查找您的文本或其他内容。然后将结果写入csv文件:

    import requests
    import pandas as pd
    from bs4 import BeautifulSoup
    import asyncio
    import re
    
    from concurrent.futures import ProcessPoolExecutor, as_completed
    
    df = pd.read_csv('test.csv')
    
    urls = df.T.values.tolist()[1]
    results = {}
    
    async def scrape(url):
        try:
            r = requests.get(url)
            soup = BeautifulSoup(r.content, 'html.parser')
            data = {
                "help": soup.body.findAll(text = re.compile("^help$", re.I)),
                "search": soup.body.findAll(text = re.compile("^search$", re.I))
            }
            results[url] = data
        except requests.exceptions.RequestException as e:
            results[url] = { "help": [], "search": []}
    
    async def main():
        await asyncio.wait([scrape(url) for url in urls])
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
    
    helpList= []
    searchList = []
    for url in urls:
        helpList.append("x" if len(results[url]["help"]) > 0 else "")
        searchList.append("x" if len(results[url]["search"]) > 0 else "")
    
    df["help"] = pd.DataFrame(helpList, columns=['help'])
    df["search"] = pd.DataFrame(searchList, columns=['search'])
    
    print(df)
    
    df.to_csv('test.csv', index=False)
    

    【讨论】:

    • 当域不存在时,我似乎得到了一个KeyError: 'https://testesttest.one'。您知道如何在循环中分别跳过和标记这些案例吗?提前致谢!
    • @Baobab1988 我添加了一个 try except requests.exceptions.RequestException as e: 来处理这个案例
    • 我测试了上面的代码,现在它会跳过所有关闭的网站,但会在没有列出关键字的网站上抛出以下错误:helpList.append("x" if len(results[url]["help"]) > 0 else "") KeyError: 'https://example.com' 有没有办法首先扫描并将网站标记为活动/非活动,然后将它们从扫描中删除,作为第二步,而不是循环异常?感谢您的帮助!
    • @Baobab1988 我无法重现这个问题,我只是在包含站点关闭的 csv 上运行脚本,站点有关键字,站点没有它
    • 我知道我在哪里犯了错误...我将关键字的代码从 "^help$" 修改为 "\W*((?i)help(?-i))\W*" - 但我认为这不是必需的,因为您的代码捕获了所有可能的命中,对吧?.它也会得到双字吗?对于状态为 404 或 403 或任何其他无法访问服务器的网站,我还尝试在我的输出 csv 文件中获取带有 x 的列 ["url_status"] 作为值。你能帮我解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多