2016-10-15 3 views
2

私はいくつかのスクレイピングコードを開発しており、他の人が助けてくれると思われるいくつかのエラーを返しています。soup.select()のdivクラスの組み合わせを修正してください

まず私はこのスニペットを実行します。

import pandas as pd 
from urllib.parse import urljoin 
import requests 

base = "http://www.reed.co.uk/jobs" 

url = "http://www.reed.co.uk/jobs?datecreatedoffset=Today&pagesize=100" 
r = requests.get(url).content 
soup = BShtml(r, "html.parser") 

df = pd.DataFrame(columns=["links"], data=[urljoin(base, a["href"]) for a in soup.select("div.pages a.page")]) 
df 

私は今日の仕事への投稿の最初のページにこのスニペットを実行します。そして、その時点で存在しているページの総数を見つけるために、ページの下部にあるURLを抽出します。以下の正規表現は私のためにこれを取る:

df['partone'] = df['links'].str.extract('([a-z][a-z][a-z][a-z][a-z][a-z]=[0-9][0-9].)', expand=True) 
df['maxlink'] = df['partone'].str.extract('([0-9][0-9][0-9])', expand=True) 
pagenum = df['maxlink'][4] 
pagenum = pd.to_numeric(pagenum, errors='ignore') 

わけではありません上記の3行目に、ページ数は、常にこのリスト内のURL(5のうちの)最後から2番目の中に含まれています。これを行うもっとエレガントな方法があると確信していますが、それだけで十分です。 URLから取得した番号をループに入力します。

result_set = [] 

loopbasepref = 'http://www.reed.co.uk/jobs?cached=True&pageno=' 
loopbasesuf = '&datecreatedoffset=Today&pagesize=100' 
for pnum in range(1,pagenum): 
    url = loopbasepref + str(pnum) + loopbasesuf 
    r = requests.get(url).content 
    soup = BShtml(r, "html.parser") 
    df2 = pd.DataFrame(columns=["links"], data=[urljoin(base, a["href"]) for a in soup.select("div", class_="results col-xs-12 col-md-10")]) 
    result_set.append(df2) 
    print(df2) 

ここでエラーが発生します。私がしようとしているのは、ページ1から開始してページNからページNに移動して各ページにリンクするURLを抽出し、それをデータフレームに格納するすべてのページをループすることです。私はsoup.select("div", class_="")のさまざまな組み合わせを試みましたが、読み取るたびにエラーが表示されます:TypeError: select() got an unexpected keyword argument 'class_'

誰もがこれについての考えを持っていて、良い方法を見ることができるなら、私は助けに感謝します!

乾杯

何の次のページが存在しなくなるまであなただけのループ保つことができクリス

+0

BShtmlはどこですか? – codervince

+0

ごめんなさい!私はbeautifulsoup4もインポートしましたが、間違って私が行った行は含まれていませんでした。 'import pandas as pd'の前に' bs4 importからBShtmlとしてBeautifulSoup'を書いた –

+0

なぜ複数のデータフレームを作成していますか? –

答えて

1

:ジェネレータ関数オーバー

import requests 
from bs4 import BeautifulSoup 
from urllib.parse import urljoin 

base = "http://www.reed.co.uk" 
url = "http://www.reed.co.uk/jobs?datecreatedoffset=Today&pagesize=100" 

def all_urls(): 
    r = requests.get(url).content 
    soup = BeautifulSoup(r, "html.parser") 
    # get the urls from the first page 
    yield [urljoin(base, a["href"]) for a in soup.select("div.details h3.title a[href^=/jobs]")] 
    nxt = soup.find("a", title="Go to next page") 
    # title="Go to next page" is missing when there are no more pages 
    while nxt: 
     # wash/repeat until no more pages 
     r = requests.get(urljoin(base, nxt["href"])).content 
     soup = BeautifulSoup(r, "html.parser") 
     yield [urljoin(base, a["href"]) for a in soup.select("div.details h3.title a[href^=/jobs]")] 
     nxt = soup.find("a", title="Go to next page") 

だけループを各ページからURLを取得するには:

for u in (all_urls()): 
    print(u) 

セレクタにもa[href^=/jobs]を使用しています一致する他のタグを再入力して、ジョブのパスを取得するようにします。独自のコードで

は、セレクタを使用するための正しい方法は次のようになります。

soup.find_all("div", class_="results col-xs-12 col-md-10") 
を見つけるために

soup.select("div.results.col-xs-12.col-md-10") 

あなたの構文は次のとおりです。あなたは、CSSクラスのclass_=...を使用find_all

しかし、それは関係なく正しいセレクターではありません。

ないのはなぜあなたが複数のDFSを作成していることを確認それはあなたが望むものである場合:

def all_urls(): 
    r = requests.get(url).content 
    soup = BeautifulSoup(r, "html.parser") 
    yield pd.DataFrame([urljoin(base, a["href"]) for a in soup.select("div.details h3.title a[href^=/jobs]")], 
         columns=["Links"]) 
    nxt = soup.find("a", title="Go to next page") 
    while nxt: 
     r = requests.get(urljoin(base, nxt["href"])).content 
     soup = BeautifulSoup(r, "html.parser") 
     yield pd.DataFrame([urljoin(base, a["href"]) for a in soup.select("div.details h3.title a[href^=/jobs]")], 
          columns=["Links"]) 
     nxt = soup.find("a", title="Go to next page") 


dfs = list(all_urls()) 

あなたのDFSのリスト与える:

In [4]: dfs = list(all_urls()) 
dfs[0].head() 
In [5]: dfs[0].head(10) 
Out[5]: 
               Links 
0 http://www.reed.co.uk/jobs/tufting-manager/308... 
1 http://www.reed.co.uk/jobs/financial-services-... 
2 http://www.reed.co.uk/jobs/head-of-finance-mul... 
3 http://www.reed.co.uk/jobs/class-1-drivers-req... 
4 http://www.reed.co.uk/jobs/freelance-middlewei... 
5 http://www.reed.co.uk/jobs/sage-200-consultant... 
6 http://www.reed.co.uk/jobs/bereavement-support... 
7 http://www.reed.co.uk/jobs/property-letting-ma... 
8 http://www.reed.co.uk/jobs/graduate-recruitmen... 
9 http://www.reed.co.uk/jobs/solutions-delivery-... 

をしかし、あなたはその後、一つだけをしたい場合itertools.chainで元のコードを使用します。

from itertools import chain 
df = pd.DataFrame(columns=["links"], data=list(chain.from_iterable(all_urls()))) 

あなたにすべてのリンク私を与えるどのndf:

In [7]: from itertools import chain 
    ...: df = pd.DataFrame(columns=["links"], data=list(chain.from_iterable(all_ 
    ...: urls()))) 
    ...: 

In [8]: df.size 
Out[8]: 675 
関連する問題