如何拆分已删除的数据并将其保存在具有完整链接和描述的csv的单独列中?

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

我正在使用Web Scraper,如果它与关键字列表匹配,则返回作业发布的链接和描述。我遇到的问题是,导出的csv只是一个长句,其中链接和描述分为一行。

如何有效地将描述和链接拆分为两个单独的列?如何才能添加链接的其余部分才能单击csv中的链接?还有一种方法可以避免csv中的重复条目吗?

这是我的代码:

from selenium import webdriver
import time, re, csv
from bs4 import BeautifulSoup as BS

keywords = ["KI", "AI", "Big Data", "Data", "data", "big data", 
"Analytics", "analytics", "digitalisierung", "ML",
"Machine Learning", "Daten", "Datenexperte", 
"Datensicherheitsexperte", "Analytikleistungen"]

browser = webdriver.Chrome()

url = "https://ausschreibungen.usp.gv.at/at.gv.bmdw.eproc-p/public"

browser.implicitly_wait(30)

browser.get(url)


innerHTML = browser.execute_script("return 
document.body.innerHTML")

soup = BS(browser.page_source, 'html.parser')

# browser.quit()
# print(soup.text)
tenders = soup.find('table', {'id': 'tenderlist'})
tbody = tenders.find('tbody')

browser.quit()


ausschreiben_found = []

for tr in tbody.find_all('tr'):
    ausschreiben = tr.find_all('td')
for keyword in keywords:
    for word in ausschreiben:
        if keyword in str(word):
            ausschreiben_found.append(word)
            print(ausschreiben_found)
with open("ausschreiben.csv", 'a', encoding='utf-8') as toWrite:
    fieldnames = ["Beschreibung", "Links"]
    writer = csv.writer(toWrite)
    writer.writerows(ausschreiben_found)
    # subprocess.call('./Autopilot3.py')
    print("Matched Ausschreiben have been collected.")
python selenium web-scraping beautifulsoup
3个回答
2
投票

由于网站使用Ajax和JavaScript库来填充页面上的表,因此获取所需数据的最简单方法是复制Ajax请求。

来自服务器的JSON数据具有以下结构:

{
    "value": {
        "draw": "-1",
        "recordsTotal": 1476,
        "recordsFiltered": 1476,
        "data": [{
            "DT_RowClass": "even",
            "0": "<a href=\"/at.gv.bmdw.eproc-p/public/de_AT/tenderlist?action=view&amp;object=41a809d9-0b61-4991-86b8-74dc07973af3-15ed14df-d91c-4905-94fd-e1d7935eaef1\">Planung Freiland/Brücke</a>",
            "1": "Autobahnen- und Schnellstraßen-Finanzierungs-Aktiengesellschaft",
            "2": "08.04.2019",
            "3": null
        }, {
            "DT_RowClass": "odd",
            "0": "<a href=\"/at.gv.bmdw.eproc-p/public/de_AT/tenderlist?action=view&amp;object=86dd87bd-7426-40c5-946b-62b2af638aab-7a54478b-9e89-4d47-bdf8-dc8b867c57b8\">Lieferung von Erdgas 2020 - 2022</a>",
            "1": "Republik Österreich (Bund), Bundesbeschaffung GmbH sowie alle weiteren Auftraggeber gemäß der den Ausschreibungsunterlagen beiliegenden Drittkundenliste, im Vergabeverfahren alle vertreten durch die Bundesbeschaffung GmbH",
            "2": "08.04.2019",
            "3": "07.05.2019"
        }]
    }
}

以下使用requests模块从服务器获取JSON,并使用最简单的HTML解析器从链接中提取文本。您可以将BeautifulSoup用于同一目的。

import requests
from html.parser import HTMLParser

class TinyTextExtractor(HTMLParser):
    def parse(self, html):
        self.text = ''
        self.feed(html)
        return self.text

    def handle_data(self, data):
        self.text += data

def get_ausschreibungen(start=0, length=25):
    url = 'https://ausschreibungen.usp.gv.at/at.gv.bmdw.eproc-p/ajax/dataTablesTenderList'
    resp = requests.get(url, {
        'start': start,
        'length': length
    })

    parser = TinyTextExtractor()

    for row in resp.json()['value']['data']:
        yield {
            'Bezeichnung': parser.parse(row['0']),
            'Organisation': row['1'],
            'Veröffentlicht':  row['2'],
            'Frist': row['3'],
        }

用法:

for item in get_ausschreibungen(0, 3):
    print(item)

哪个打印出来给我:

{'Bezeichnung': 'Planung Freiland/Brücke', 'Organisation': 'Autobahnen- und Schnellstraßen-Finanzierungs-Aktiengesellschaft', 'Veröffentlicht': '08.04.2019', 'Frist': None}
{'Bezeichnung': 'Lieferung von Erdgas 2020 - 2022', 'Organisation': 'Republik Österreich (Bund), Bundesbeschaffung GmbH sowie alle weiteren Auftraggeber gemäß der den Ausschreibungsunterlagen beiliegenden Drittkundenliste, im Vergabeverfahren alle vertreten durch die Bundesbeschaffung GmbH', 'Veröffentlicht': '08.04.2019', 'Frist': '07.05.2019'}
{'Bezeichnung': 'Umbau Bahnhof Villach ', 'Organisation': 'ÖBB-Personenverkehr AG', 'Veröffentlicht': '08.04.2019', 'Frist': None}

我确信过滤/将其转换为CSV不再是问题。

使用浏览器的开发人员工具(F12)确定发送的其他请求参数以及它们是否与您相关。你也可以尝试使用requests模块的Session功能“混入”,复制所有的HTTP标头和cookie,但鉴于这似乎是一个政府网站,他们可能不会介意你正在抓它们。


0
投票

写在单独的列中

reader = csv.DictReader(f) # open and write mode opened file
csvWriter = csv.writer(f)
existing_queries = set()
for row in reader:
    if reader.line_num == 1:
       continue
if row['link'] in existing_queries:
    print("Already exists")
else:
    csvWriter.writerow("description", "link") # will write
    existing_queries.add("description", "link")


我希望这有帮助


-1
投票

使用csv.writer类的换行符和分隔符参数

你可以在这里找到例子:https://docs.python.org/3/library/csv.html#writer-objects

© www.soinside.com 2019 - 2024. All rights reserved.