如何使用 Python 抓取和抓取此特定网站并将数据保存在文本文件中?

编程入门 行业动态 更新时间:2024-10-28 07:22:28
本文介绍了如何使用 Python 抓取和抓取此特定网站并将数据保存在文本文件中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

好的,所以我正在做这个项目,它在孟加拉语网络语料库上实现 Word2Vec 以查找类似的上下文词,作为先决条件,我正在尝试抓取某些新闻和博客网站,然后抓取链接以构建一个数据语料库.目前,我正在 Chrome 浏览器上使用 Google Colab.

这是我用于抓取的 Python 代码...(我确实从互联网上获取了代码片段的帮助,我最近才了解了所有这些)

<预><代码>进口请求导入 urllib.parse从 urllib.parse 导入 urlparse, urljoin从 bs4 导入 BeautifulSoup进口彩绘从 urllib.request 导入 urlopen从 urllib.request 导入请求# 初始化colorama模块colorama.init()绿色 = colorama.Fore.GREEN灰色 = colorama.Fore.LIGHTBLACK_EXRESET = colorama.Fore.RESET黄色 = colorama.Fore.YELLOW# 初始化链接列表(唯一链接)internal_urls = set() #所有内部链接的集合external_urls = set() #所有外部链接的集合old_internals #在包含另一个内部链接之前跟踪内部链接def is_valid(url):"检查 `url` 是否是一个有效的 URL."解析 = urlparse(url)返回 bool(parsedloc) 和 bool(parsed.scheme)"返回在属于同一网站的 `url` 上找到的所有 URL"# `url 的所有 URLdef get_all_website_links(url):全局 old_internals尝试:网址 = 设置()# 不带协议的URL的域名domain_name = urlparse(url)locuser_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'req = Request(url, headers={'User-Agent': user_agent})文章 = urlopen(req).read()汤 = BeautifulSoup(文章,lxml")old_internals = internal_urls.copy() #复制旧的内部链接集对于soup.findAll(a")中的a_tag:#Links under <a>标签href = a_tag.attrs.get("href")如果 href == "";或 href 为 None:# href 空标签继续# 如果 URL 是相对的(不是绝对链接),则加入 URLhref = urljoin(url, href)parsed_href = urlparse(href)# 移除 URL GET 参数、URL 片段等.href = parsed_href.scheme + "://";+ parsed_hrefloc + parsed_href.path如果不是 is_valid(href):# 不是一个有效的网址继续如果internal_urls中的href:# 已经在集合中继续如果 domain_name 不在 href 中:# 外部链接如果 href 不在 external_urls 中:print(f"{GRAY}[!] 外部链接:{href}{RESET} \n")external_urls.add(href)继续打印(f{GREEN}[*] 内部链接:{href}{RESET} \n")urls.add(href)internal_urls.add(href)#我绝对可以将其作为函数来完成#而不是再次编写整个代码,但是...#(我会改的)对于soup.findAll(link")中的link_tag:#Links under <link>标签href = link_tag.attrs.get("href")如果 href == "";或 href 为 None:# href 空标签继续# 如果 URL 是相对的(不是绝对链接),则加入 URLhref = urljoin(url, href)parsed_href = urlparse(href)# 移除 URL GET 参数、URL 片段等.href = parsed_href.scheme + "://";+ parsed_hrefloc + parsed_href.path如果不是 is_valid(href):# 不是一个有效的网址继续如果internal_urls中的href:# 已经在集合中继续如果 domain_name 不在 href 中:# 外部链接如果 href 不在 external_urls 中:print(f"{GRAY}[!] 外部链接:{href}{RESET} \n")external_urls.add(href)继续打印(f{GREEN}[*] 内部链接:{href}{RESET} \n")urls.add(href)internal_urls.add(href)返回网址除了作为 e 的例外:#如果添加的链接有问题,只返回列表#旧的内部链接.该函数返回错误并停止#crawling 因为某些内部链接在最大计数为中途#大,所以...打印(\n")打印(e)打印(\n无返回\n")#print(internal_urls, "\n\n")返回 old_internals# 到目前为止访问过的 url 数量将存储在这里total_urls_visited = 0def crawl(url, max_urls=30):"抓取网页并提取所有链接.您将在external_urls"和internal_urls"全局设置变量中找到所有链接.参数:max_urls (int): 要抓取的最大 url 数,默认为 30."全局 total_urls_visitedtotal_urls_visited += 1#打印(网址)打印(f{YELLOW}[*] 爬行:{url}{RESET} \n")链接 = get_all_website_links(url)loop=links.copy() #因为返回旧的内部链接可能会改变循环大小for 循环链接:如果 total_urls_visited >最大网址:休息爬网(链接,max_urls)def extract_name(link_url): #给文件命名的程序名称="link_name= link_url[link_url.index(":")+3:] #跳过https://";部分 :)link_name=link_name.replace('/', '_')link_name=link_name.replace('.', '_')link_name=link_name.replace(' ', '_')link_name=link_name.replace('-', '_')返回链接名称+.txt";def fileWrite(fname, lst):a_file = open(fname, wb")对于 lst 中的元素:l = len(元素)如果 l == 0:继续a_file.write(element.encode() + "\n".encode())a_file.close()#运行如果 __name__ == __main__":max_urls =#任意孟加拉网站链接列表web_links=[https://www.anandabazar/",https://www.prothomalo/",https://www.littlemag/2019/05/blog-post_60.html"]#列表中网页链接的索引指数=1爬网(web_links [index],max_urls)fname=extract_name(web_links[index])文件写入(fname,internal_urls)打印([+] 内部链接总数:",len(internal_urls))打印([+] 外部链接总数:",len(external_urls))打印([+] 总 URL:",len(external_urls) + len(internal_urls))打印([+] 总爬取的网址:",max_urls)

现在我的代码在前两个站点 [索引 0, 1] 上运行没有任何问题,我认为这是因为当我在 chrome 浏览器上访问该站点时,我什至可以手动复制文本.

但是索引为 2 的站点,即https://www.littlemag/2019/05/blog-post_60.html,它根本不起作用.而且我也无法在浏览器上复制或选择任何内容.我该如何解决这个问题并抓取本网站域上的链接?

同样的问题出现在我的网页抓取代码上...

将 bs4 导入为 bs导入 urllib.request从 urllib.request 导入请求,urlopenweb_links=[https://www.anandabazar/",https://www.prothomalo/",https://www.littlemag/2019/05/blog-post_60.html"]user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'req = Request(web_links[2], headers={'User-Agent': user_agent})文章 = urlopen(req).read()#打印(文章)parsed_article = bs.BeautifulSoup(文章,'lxml')#我读到博客和新闻网站上文章的主要内容存储在<p>标签,#(我不记得我在 html 中学习的所有内容)请随时告诉我,#如果我也应该包括其他东西.段落 = parsed_article.find_all('p')article_text = "";对于段落中的 p:article_text += ""+ p.text打印(文章文本)

我无法从本网站上的孟加拉文文章中获取或抓取任何数据,https://www.littlemag/2019/05/blog-post_60.html,并在 Colab 控制台上打印.我应该在这两个代码中进行哪些更改以解决此问题并包含来自这些现在可复制、可选择的站点的数据?


更新:

谢谢安德烈·凯塞利.我的网站抓取问题已解决,但我想知道是否有办法使用您的代码抓取该页面中的标题?

soup.find_all([repile('^h[1-6]$'), 'p']) 中的内容:打印(内容.文本)

在这种情况下,这对我不起作用.

还有一段代码,

导入请求从 bs4 导入 BeautifulSoupurl = "https://www.littlemag/2019/05/blog-post_60.html";汤 = BeautifulSoup(requests.get(url).content, html.parser")打印(soup.select_one(.post-body")).get_text(strip=True,separator=\n"))

它不适用于 https://www.littlemag/,这是我们正在处理的网站的主页.

给出错误 AttributeError: 'NoneType' object has no attribute 'get_text'.

可能是什么原因以及如何从主页获取内容和标题,https://www.littlemag/ ?

解决方案

要从此站点获取帖子文本,您可以使用下一个示例:

导入请求从 bs4 导入 BeautifulSoupurl = "https://www.littlemag/2019/05/blog-post_60.html";汤 = BeautifulSoup(requests.get(url).content, html.parser")打印(soup.select_one(.post-body")).get_text(strip=True,separator=\n"))

打印:

● ছবিতে - বাঙালির পাতের চির নঁীীোো্■পদ্মপুরাণেবেহুলারবিয়েরনিরামিষখাবারেরমধ্যেশুক্তোরউল্লেখপাওয়াযায়.ভারতচন্দ্রেরঅন্নদামঙ্গলেওবাইশরকমেরনিরামিষপদেরমধ্যেশুক্তুনিকেপাওয়াযায়.মঙ্গলকাব্যওবৈষ্ণবসাহিত্যেএইরান্নাটিরবহুবারউল্লেখপাওয়াযায়.কিন্তুবর্তমানে 'শুক্তো' বলতেযেমনউচ্ছে,করলা,পল্তা,নিম,সিম,বেগুনপ্রভৃতিসবজিরতিক্তব্যঞ্জনকেবোঝায়,প্রাচীনকালেতাছিলনা.একালের শুক্তোকে সেকালে 'তিতো' বলাহথসেকালে 'শুক্তা' রান্নাকরাহত-বেগুন,কাঁচাকুমড়ো,কাঁচকলা,মোচাএইসবজিগুলিগুঁড়োবাবাটামসলাঅথবাবেসনেরসঙ্গেবেশভালোকরেমেখেবানেড়েনিয়েঘন 'পিঠালি' মিশিয়েরান্নাকরাহত.পরে হিং, জিরাও মেথিকিন্তু 'চৈতন্যচরিতামৃতে' সুকুতা,শুকুতাবাসুক্তাবলতেএকধরণেরশুকনোপাতাকেবলাহয়েছে.এটি ছিল আম-নাশক।সম্ভবত এটি ছিল শুকনো তিতো পাটপাতা।রাঘবপণ্ডিতমহাপ্রভুরজন্যনীলাচলেযেসবজিনিসনিয়েগিয়েছিলেনতারমধ্যেএইদ্রব্যটিওছিল.আবার 'সুকুতা' বলতেসেইসময়শুকনোশাকেরব্যঞ্জনকেওবোঝাত.বাঙালির চিরকালের পরিচয় ‘ভেতো বাঙালিঅর্থাৎযাদেরপ্রধানখাদ্যহলোভাত।প্রাচীনকালেগরিববাঙালিরমুখেশোনাযেতদুঃখেরকাঁদুনী,হাড়িতভাতনাহিনিতিআবেশী"(চর্যাপদ).মানে ‘ঘরে ভাতনেই তবু অতিথিরতবেধনী-নির্ধনসববাঙালিরপ্রিয়খাদ্যগরমভাতেগাওয়াঘি.যারাদিনআনেদিনখায়,তাঁদেরচরমপ্রাপ্তিহলো - পান্তাভাতেবাইগনপোড়া.পণ্ডিতরাবলেন,প্রকৃতবাঙালিরমনমতোখাবারছিলকলাপাতায়ওগ্গারাভত্তাগাইকঘিত্তা",অর্থাৎগাওয়াঘিআরফেনাভাত.দুধ আর সরু চাল মিশিয়ে পায়েসবড়মািরযরয...

Ok, so I'm doing this project which implements Word2Vec on a Bengali language web corpus to find similar contextual words of words and as pre-requisite I am trying to crawl certain news and blog sites and then scraping the links to build a data corpus. I'm using Google Colab on my Chrome browser, as of now.

Here's my Python code for crawling... (I did take help from the internet for code snippets, I have only recently learnt all of this)


import requests
import urllib.parse
from urllib.parse import urlparse, urljoin
from bs4 import BeautifulSoup
import colorama
from urllib.request import urlopen
from urllib.request import Request

# init the colorama module
colorama.init()
GREEN = colorama.Fore.GREEN
GRAY = colorama.Fore.LIGHTBLACK_EX
RESET = colorama.Fore.RESET
YELLOW = colorama.Fore.YELLOW

# initialize the list of links (unique links)
internal_urls = set() #Set of All internal links
external_urls = set() #Set of All external links
old_internals #Keeps track of internal links before including another


def is_valid(url):
    """
    Checks whether `url` is a valid URL.
    """
    parsed = urlparse(url)
    return bool(parsedloc) and bool(parsed.scheme)


"""
Returns all URLs that is found on `url` in which it belongs to the same website
"""
# all URLs of `url
def get_all_website_links(url):
    global old_internals
    try:
        urls = set()
        # domain name of the URL without the protocol
        domain_name = urlparse(url)loc
        user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
        req = Request(url, headers={'User-Agent': user_agent})
        article = urlopen(req).read()
        soup = BeautifulSoup(article, "lxml")

        old_internals = internal_urls.copy() #Copies old set of internal links

        for a_tag in soup.findAll("a"): #Links under  <a> tag
            href = a_tag.attrs.get("href")
            if href == "" or href is None:
                # href empty tag
                continue
            # join the URL if it's relative (not absolute link)
            href = urljoin(url, href)

            parsed_href = urlparse(href)
            # remove URL GET parameters, URL fragments, etc.
            href = parsed_href.scheme + "://" + parsed_hrefloc + parsed_href.path
            if not is_valid(href):
                # not a valid URL
                continue
            if href in internal_urls:
                # already in the set
                continue
            if domain_name not in href:
                # external link
                if href not in external_urls:
                    print(f"{GRAY}[!] External link: {href}{RESET} \n")
                    external_urls.add(href)
                continue
            print(f"{GREEN}[*] Internal link: {href}{RESET} \n")
            urls.add(href)
            internal_urls.add(href)

        #I could definitely have done this as a function
        #instead of writing the whole code again, but well...
        #(I will change it)
        for link_tag in soup.findAll("link"): #Links under <link> tag
            href = link_tag.attrs.get("href")
            if href == "" or href is None:
                # href empty tag
                continue
            # join the URL if it's relative (not absolute link)
            href = urljoin(url, href)
            parsed_href = urlparse(href)
            # remove URL GET parameters, URL fragments, etc.
            href = parsed_href.scheme + "://" + parsed_hrefloc + parsed_href.path
            if not is_valid(href):
                # not a valid URL
                continue
            if href in internal_urls:
                # already in the set
                continue
            if domain_name not in href:
                # external link
                if href not in external_urls:
                    print(f"{GRAY}[!] External link: {href}{RESET} \n")
                    external_urls.add(href)
                continue
            print(f"{GREEN}[*] Internal link: {href}{RESET} \n")
            urls.add(href)            
            internal_urls.add(href)
        return urls
    except Exception as e: 
        #If the link to be added were problematic, just return the list of
        #old internal links. The function was returning an error and stopped 
        #crawling because of certain internal links midway when max count was
        #large, so...
        print("\n")
        print(e)
        print("\nNone returned\n")
        #print(internal_urls, "\n\n")
        return old_internals

# number of urls visited so far will be stored here
total_urls_visited = 0

def crawl(url, max_urls=30):
    """
    Crawls a web page and extracts all links.
    You'll find all links in `external_urls` and `internal_urls` global set variables.
    params:
        max_urls (int): number of max urls to crawl, default is 30.
    """
    global total_urls_visited
    total_urls_visited += 1
    #print(url)
    print(f"{YELLOW}[*] Crawling: {url}{RESET} \n")
    links = get_all_website_links(url)
    loop=links.copy() #Since returning old internal links may change loop size
    for link in loop:
        if total_urls_visited > max_urls:
            break
        crawl(link, max_urls)

def extract_name(link_url): #Program to name the file
  name=""
  link_name= link_url[link_url.index(":")+3:] #skips the "https://" part :)
  link_name=link_name.replace('/', '_')
  link_name=link_name.replace('.', '_')
  link_name=link_name.replace(' ', '_')
  link_name=link_name.replace('-', '_')
  return link_name+".txt"

def fileWrite(fname, lst):
    a_file = open(fname, "wb")
    for element in lst:
      l = len(element)
      if l == 0:
        continue
      a_file.write(element.encode() + "\n".encode())
    a_file.close()

#Runtime
if __name__ == "__main__":
    max_urls = 
    #Arbitrary list of links of Bengali sites
    web_links=["https://www.anandabazar/",
               "https://www.prothomalo/",
               "https://www.littlemag/2019/05/blog-post_60.html"]
    
    #Index of weblink in list
    index=1

    crawl(web_links[index], max_urls)
    fname=extract_name(web_links[index])
    fileWrite(fname, internal_urls)

    print("[+] Total Internal links:", len(internal_urls))
    print("[+] Total External links:", len(external_urls))
    print("[+] Total URLs:", len(external_urls) + len(internal_urls))
    print("[+] Total crawled URLs:", max_urls)

Now my code works without any issues for the first two sites [indices 0, 1] which I presume is because I can even copy the text manually when I go to that site on my chrome browser.

But the site with the index=2, i.e. https://www.littlemag/2019/05/blog-post_60.html, it doesn't work at all. And I can't copy or select anything on the browser either. How do I work about this problem and crawl links on the domain of this site?

The same issue is showing up on my web scraping code...

import bs4 as bs
import urllib.request
from urllib.request import Request, urlopen

web_links=["https://www.anandabazar/", 
           "https://www.prothomalo/", 
           "https://www.littlemag/2019/05/blog-post_60.html"]

user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
req = Request(web_links[2], headers={'User-Agent': user_agent})
article = urlopen(req).read()

#print(article)

parsed_article = bs.BeautifulSoup(article, 'lxml')

#I read that the main content of articles on blogs and news sites is stored in the <p> tag,
#(I don't remember everything I studied in html) please feel free to let me know,
#if I should include something else too.

paragraphs = parsed_article.find_all('p')
article_text = ""

for p in paragraphs:
    article_text += " " + p.text

print(article_text)

I can't fetch or scrape any data from the Bengali article on this site, https://www.littlemag/2019/05/blog-post_60.html, and print it on the Colab console. What should I change in the two codes to work this about and include data from these now copy-able, selectable sites?


Update:

Thank you Andrej Kesely. My problem with scraping of the site is solved, but I would like to know if there is a way to scrape the headings within that page, using your code?

for content in soup.find_all([repile('^h[1-6]$'), 'p']):     
    print(content.text)

This won't work for me, in this case.

Also the piece of code,

import requests
from bs4 import BeautifulSoup

url = "https://www.littlemag/2019/05/blog-post_60.html"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

print(soup.select_one(".post-body").get_text(strip=True, separator="\n"))

It is not working for, https://www.littlemag/, which is the homepage of the site we are dealing with.

Gives the error AttributeError: 'NoneType' object has no attribute 'get_text'.

What could be the reason and how can I fetch the content along with heading from the homepage as well, https://www.littlemag/ ?

解决方案

To get post text from this site you can use next example:

import requests
from bs4 import BeautifulSoup

url = "https://www.littlemag/2019/05/blog-post_60.html"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

print(soup.select_one(".post-body").get_text(strip=True, separator="\n"))

Prints:

● ছবিতে - বাঙালির পাতের চির নবীন শুক্তো।
■ পদ্মপুরাণে বেহুলার বিয়ের নিরামিষ খাবারের মধ্যে শুক্তোর উল্লেখ পাওয়া যায়। ভারতচন্দ্রের অন্নদামঙ্গলেও বাইশ রকমের নিরামিষ পদের মধ্যে শুক্তুনিকে পাওয়া যায়।
মঙ্গলকাব্য ও বৈষ্ণবসাহিত্যে এই রান্নাটির বহুবার উল্লেখ পাওয়া যায়। কিন্তু বর্তমানে 'শুক্তো' বলতে যেমন উচ্ছে, করলা, পল্‌তা, নিম, সিম, বেগুন প্রভৃতি সবজির তিক্ত ব্যঞ্জনকে বোঝায়, প্রাচীনকালে তা ছিল না। একালের শুক্তোকে সেকালে 'তিতো' বলা হত।
সেকালে 'শুক্তা' রান্না করা হত- বেগুন, কাঁচা কুমড়ো, কাঁচকলা, মোচা এই সবজিগুলি গুঁড়ো বা বাটা মসলা অথবা বেসনের সঙ্গে বেশ ভালো করে মেখে বা নেড়ে নিয়ে ঘন 'পিঠালি' মিশিয়ে রান্না করা হত। পরে হিং, জিরা ও মেথি দিয়ে ঘিয়ে সাঁতলিয়ে নামাতে হত।
কিন্তু 'চৈতন্যচরিতামৃতে' সুকুতা, শুকুতা বা সুক্তা বলতে একধরণের শুকনো পাতাকে বলা হয়েছে। এটি ছিল আম-নাশক। সম্ভবত এটি ছিল শুকনো তিতো পাটপাতা। রাঘব পণ্ডিত মহাপ্রভুর জন্য নীলাচলে যেসব জিনিস নিয়ে গিয়েছিলেন তার মধ্যে এই দ্রব্যটিও ছিল।
আবার 'সুকুতা' বলতে সেই সময় শুকনো শাকের ব্যঞ্জনকেও বোঝাত।
বাঙালির চিরকালের পরিচয় ‘ভেতো বাঙালি’। অর্থাৎ যাদের প্রধান খাদ্য হলো ভাত। প্রাচীনকালে গরিব বাঙালির মুখে শোনা যেত দুঃখের কাঁদুনী, ‘হাড়িত ভাত নাহি নিতি আবেশী’ (চর্যাপদ)। মানে ‘ঘরে ভাত নেই তবু অতিথির আসা যাওয়ার কমতি নেই’। তবে ধনী-নির্ধন সব বাঙালির প্রিয় খাদ্য গরম ভাতে গাওয়া ঘি। যারা দিন আনে দিন খায়, তাঁদের চরম প্রাপ্তি হলো — পান্তা ভাতে বাইগন পোড়া। পণ্ডিতরা বলেন, প্রকৃত বাঙালির মনমতো খাবার ছিল কলাপাতায় ‘ওগ্গারা ভত্তা গাইক ঘিত্তা’, অর্থাৎ গাওয়া ঘি আর ফেনা ভাত। দুধ আর সরু চাল মিশিয়ে পায়েস বড়মানুষের প্রিয় খাদ্য।

...

这篇关于如何使用 Python 抓取和抓取此特定网站并将数据保存在文本文件中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

更多推荐

[db:关键词]

本文发布于:2023-04-26 16:18:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1139278.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:并将   如何使用   文本文件   数据   网站

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!